iOS自定义segment实现视图切换

来源:互联网 发布:恒智天成软件 编辑:程序博客网 时间:2024/06/10 15:16
好久没有更新博客了,最近活比较忙,可能有3个礼拜没有来更新博客了。近期在做项目的时候,需求需要App中有一个可以控制视图切换的控件,其实原理就是ios中的segment控件,但是sdk中的控件过于官方化,项目需要按照自己的设计图来实现它。所以研究了一下自己写了一个类似segment的控件,在这里跟大家分享一下。ps:控件外观还需要需改,这里只是将我实现的原理跟大家分享一下。

先看效果图:


通过点击下面的控件来实现视图的切换,当前的按钮会更改外观,而其他的按钮则会恢复未点击的效果。

逻辑代码如下:

[objc] view plaincopy
  1. //  
  2. //  CustomSegmentView.h  
  3. //  PanderStrategy  
  4. //  
  5. //  Created by silicon on 14-9-2.  
  6. //  Copyright (c) 2014年 silicon. All rights reserved.  
  7. //  
  8.   
  9. #import <UIKit/UIKit.h>  
  10. #import "UIButton+Icon.h"  
  11.   
  12. @protocol CustomDelegate <NSObject>  
  13.   
  14. - (void)buttonClick:(NSInteger)sender;  
  15.   
  16. - (void)topButtonClick:(NSString *)sender;  
  17.   
  18. @end  
  19.   
  20.   
  21. @interface CustomSegmentView : UIView  
  22.   
  23. @property (nonatomicstrongUIColor *cusBkColor;  
  24. @property (nonatomicstrongUIColor *cusSelColor;  
  25. @property (nonatomicstrongNSMutableArray *segmentArray;  
  26. @property (nonatomicstrongUIColor *cusTextColor;  
  27. @property (assign) float cusbWidth;  
  28. @property (nonatomicstrongUIColor *cusbColor;  
  29. @property (strongnonatomicid<CustomDelegate>myDelagte;  
  30.   
  31.   
  32. - (id)initWithFrame:(CGRect)frame  
  33.        segmentArray:(NSArray *)_array  
  34.          background:(UIColor *)_bkColor  
  35.       selectedColor:(UIColor *)_selColor  
  36.         borderColor:(UIColor *)_bColor  
  37.         borderWidth:(float)_bWidth  
  38.            textFont:(UIFont *)_font  
  39.           textColor:(UIColor *)_textColor  
  40.            position:(NSString *)_position;  
  41.   
  42. //- (id)initWithOtherFrame:(CGRect)frame  
  43. //       segmentArray:(NSArray *)_array  
  44. //         background:(UIColor *)_bkColor  
  45. //      selectedColor:(UIColor *)_selColor  
  46. //        borderColor:(UIColor *)_bColor  
  47. //        borderWidth:(float)_bWidth  
  48. //           textFont:(UIFont *)_font  
  49. //          textColor:(UIColor *)_textColor  
  50. //           position:(NSString *)_position;  
  51.   
  52.   
  53.   
  54.   
  55.   
  56. @end  

实现文件:

[objc] view plaincopy
  1. //  
  2. //  CustomSegmentView.m  
  3. //  PanderStrategy  
  4. //  
  5. //  Created by silicon on 14-9-2.  
  6. //  Copyright (c) 2014年 silicon. All rights reserved.  
  7. //  
  8.   
  9. #import "CustomSegmentView.h"  
  10.   
  11. @implementation CustomSegmentView  
  12. @synthesize cusBkColor = _cusBkColor;  
  13. @synthesize cusSelColor = _cusSelColor;  
  14. @synthesize segmentArray = _segmentArray;  
  15. @synthesize cusTextColor = _cusTextColor;  
  16.   
  17. - (id)initWithFrame:(CGRect)frame  
  18.        segmentArray:(NSArray *)_array  
  19.          background:(UIColor *)_bkColor  
  20.       selectedColor:(UIColor *)_selColor  
  21.         borderColor:(UIColor *)_bColor  
  22.         borderWidth:(float)_bWidth  
  23.            textFont:(UIFont *)_font  
  24.           textColor:(UIColor *)_textColor  
  25.            position:(NSString *)_position  
  26. {  
  27.     self = [super initWithFrame:frame];  
  28.     if (self) {  
  29.         // Initialization code  
  30.         [self setBackgroundColor:_bkColor];  
  31.         self.cusBkColor = _bkColor;  
  32.         self.cusSelColor = _selColor;  
  33.         self.cusTextColor = _textColor;  
  34.         self.cusbWidth = _bWidth;  
  35.         self.cusbColor = _bColor;  
  36.           
  37.         self.segmentArray = [[NSMutableArray alloc] init];  
  38.           
  39.         float width = frame.size.width/_array.count;  
  40.         for (int i = 0; i < [_array count]; i++) {  
  41.             UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(width * i, 0, width, frame.size.height)];  
  42. //            [btn setImageWithTitle:[UIImage imageNamed:@"email"] withTitle:[_array objectAtIndex:i] position:@"right" font:_font forState:UIControlStateNormal];  
  43.               
  44.             //不需要图片与文字一起显示  
  45.             [btn setTitle:[_array objectAtIndex:i] forState:UIControlStateNormal];  
  46.             [btn setFont:_font];  
  47.               
  48.             [btn addTarget:self action:@selector(clickSegment:) forControlEvents:UIControlEventTouchUpInside];  
  49.               
  50.             [_segmentArray addObject:btn];  
  51.             [self addSubview:btn];  
  52.         }  
  53.         self.layer.masksToBounds=YES;  
  54.     }  
  55.     return self;  
  56. }  
  57.   
  58.   
  59. //- (id)initWithOtherFrame:(CGRect)frame segmentArray:(NSArray *)_array background:(UIColor *)_bkColor selectedColor:(UIColor *)_selColor borderColor:(UIColor *)_bColor borderWidth:(float)_bWidth textFont:(UIFont *)_font textColor:(UIColor *)_textColor position:(NSString *)_position{  
  60. //    self = [super initWithFrame:frame];  
  61. //    if (self) {  
  62. //        // Initialization code  
  63. //        [self setBackgroundColor:_bkColor];  
  64. //        self.cusBkColor = _bkColor;  
  65. //        self.cusSelColor = _selColor;  
  66. //        self.cusTextColor = _textColor;  
  67. //        self.cusbWidth = _bWidth;  
  68. //        self.cusbColor = _bColor;  
  69. //          
  70. //        self.segmentArray = [[NSMutableArray alloc] init];  
  71. //          
  72. //        float width = frame.size.width/_array.count;  
  73. //        for (int i = 0; i < [_array count]; i++) {  
  74. //            UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(width * i, 0, width, frame.size.height)];  
  75. //            [btn setTitle:[_array objectAtIndex:i] forState:UIControlStateNormal];  
  76. //            [btn setFont:_font];  
  77. //            [btn addTarget:self action:@selector(clickOtherSegment:) forControlEvents:UIControlEventTouchUpInside];  
  78. //              
  79. //            [_segmentArray addObject:btn];  
  80. //            [self addSubview:btn];  
  81. //        }  
  82. //        self.layer.masksToBounds=YES;  
  83. //    }  
  84. //    return self;  
  85. //}  
  86.   
  87. /* 
  88. // Only override drawRect: if you perform custom drawing. 
  89. // An empty implementation adversely affects performance during animation. 
  90. - (void)drawRect:(CGRect)rect 
  91. { 
  92.     // Drawing code 
  93. } 
  94. */  
  95.   
  96. - (void)clickSegment:(id)sender{  
  97.     UIButton *btn = (UIButton *)sender;  
  98.     NSUInteger index = [_segmentArray indexOfObject:btn];  
  99.       
  100.     [self.myDelagte buttonClick:index];  
  101.     [self updateSegmentStates:index];  
  102.       
  103. }  
  104.   
  105. //- (void)clickOtherSegment:(id)sender{  
  106. //    UIButton *btn = (UIButton *)sender;  
  107. //    NSUInteger index = [_segmentArray indexOfObject:btn];  
  108. //      
  109. //    [self.myDelagte topButtonClick:btn.titleLabel.text];  
  110. //    [self updateSegmentStates:index];  
  111. //}  
  112.   
  113. - (void)updateSegmentStates:(NSUInteger )index{  
  114.     self.layer.borderWidth=self.cusbWidth;  
  115.     self.layer.borderColor=self.cusbColor.CGColor;  
  116.       
  117.     for (int i = 0; i < [_segmentArray count]; i++) {  
  118.         if(i == index){  
  119.             UIButton *btn = [_segmentArray objectAtIndex:index];  
  120.             [btn setBackgroundColor:_cusSelColor];  
  121.             [btn setTitleColor:_cusTextColor forState:UIControlStateNormal];  
  122.         }else{  
  123.             UIButton *btn = [_segmentArray objectAtIndex:i];  
  124.             [btn setBackgroundColor:_cusBkColor];  
  125.             [btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];  
  126.         }  
  127.     }  
  128. }  
  129. @end<span style="color: rgb(255, 255, 255); font-family: Menlo; font-size: 13px;">egmentView</span>  



接下来,我们就来分析一下代码:

CustomSegmentView继承自UIView,这样在它初始化完成以后,我们就可以直接得到一个UIview的类型,然后通过addSubView的方式将他加入到主视图中。

我将他的initWithFrame函数扩展了一下,使它可以传入我们自定义的参数来初始化视图。

- (id)initWithFrame:(CGRect)frame

       segmentArray:(NSArray *)_array

         background:(UIColor *)_bkColor

      selectedColor:(UIColor *)_selColor

        borderColor:(UIColor *)_bColor

        borderWidth:(float)_bWidth

           textFont:(UIFont *)_font

          textColor:(UIColor *)_textColor

           position:(NSString *)_position


segmentArray:存放需要显示的视图名称标题

background:背景色

selectedColor:选中状态颜色

borderColor:边框颜色

borderWidth:边框粗细

textFont:标题字体及大小

textColor:字体颜色

position:显示位置,这个参数的作用是当segment中需要显示文字加图标的形式的时候,来定义图标显示方位的参数


逻辑代码很简单直接看源码就能理解了。


- (void)clickSegment:(id)sender函数是按钮响应的函数,在该类中,我们使用了代理的方式,告知使用该控件的视图,用户是点击的哪一个视图。


- (void)updateSegmentStates:(NSUInteger )index:函数则是用于更新按钮状态的函数,当某一个按钮被几点之后,外观需要怎么更改,以及其他未被点击的按钮背景外观如何

显示。


@protocol CustomDelegate <NSObject>


- (void)buttonClick:(NSInteger)sender;


- (void)topButtonClick:(NSString *)sender;


@end


则是我定义的代理,ios代理模式怎么使用我这里就不加解释了,我之前的文章有讲过,用户可自行查看。


接下来,由于有时候要显示的时图片加标题形式的segment,类似微信的底端,如图所示:



因为我们添加的都是UIButton,如果要显示成带文字跟图片的那我目前能想到的就只有两种情况,一种就是做背景图片文件跟图标一起做上去,然后点击的时候换背景。

还有一种情况就是我们去扩展一下UIButton的类别,使之可以支持文字跟图片。既然做开发么,当然不能偷懒选择第一种方式了,除非万不得已哦。我自定义了一个

UIButton+Icon的类别,然后在里面添加了扩展函数,代码如下:

[objc] view plaincopy
  1. #import <Foundation/Foundation.h>  
  2.   
  3. @interface UIButton (CustomBtn)  
  4.   
  5. - (void)setImageWithTitle:(UIImage *)image withTitle:(NSString *)title position:(NSString *)_position font:(UIFont *)_font forState:(UIControlState)stateType;  
  6.   
  7. @end  

[objc] view plaincopy
  1. #import "UIButton+Icon.h"  
  2.   
  3. @implementation UIButton (CustomBtn)  
  4.   
  5. - (void)setImageWithTitle:(UIImage *)image withTitle:(NSString *)title position:(NSString *)_position font:(UIFont *)_font forState:(UIControlState)stateType{  
  6.     CGSize titleSize = [title sizeWithFont:[UIFont systemFontOfSize:11.0f]];  
  7.     [self.imageView setContentMode:UIViewContentModeCenter];  
  8.       
  9.     if([_position isEqualToString:@"left"]){  
  10.         [self setImageEdgeInsets:UIEdgeInsetsMake((self.frame.size.height - 50)/210.00.00)];  
  11.     }else if([_position isEqualToString:@"top"]){  
  12.         [self setImageEdgeInsets:UIEdgeInsetsMake(5.00.020.0, -titleSize.width)];  
  13.     }else if([_position isEqualToString:@"right"]){  
  14.         [self setImageEdgeInsets:UIEdgeInsetsMake((self.frame.size.height - 50)/2, titleSize.width + 250.00.0)];  
  15.     }  
  16.   
  17.       
  18.     [self setImage:image forState:stateType];  
  19.       
  20.     [self.titleLabel setContentMode:UIViewContentModeCenter];  
  21.     [self.titleLabel setBackgroundColor:[UIColor clearColor]];  
  22.     [self.titleLabel setFont:_font];  
  23.       
  24.     if([_position isEqualToString:@"left"]){  
  25.         [self setTitleEdgeInsets:UIEdgeInsetsMake((self.frame.size.height - 50)/2,  
  26.                                                   image.size.width,  
  27.                                                   0.0,  
  28.                                                   0.0)];  
  29.     }else if([_position isEqualToString:@"top"]){  
  30.         [self setTitleEdgeInsets:UIEdgeInsetsMake(30.0,  
  31.                                                   -image.size.width,  
  32.                                                   0.0,  
  33.                                                   0.0)];  
  34.     }else if([_position isEqualToString:@"right"]){  
  35.         [self setTitleEdgeInsets:UIEdgeInsetsMake((self.frame.size.height - 50)/2,  
  36.                                                   -40.0,  
  37.                                                   0.0,  
  38.                                                   0)];  
  39.     }  
  40.       
  41.       
  42.     [self setTitle:title forState:stateType];  
  43. }  
  44.   
  45. @end  

- (void)setImageWithTitle:(UIImage *)image withTitle:(NSString *)title position:(NSString *)_position font:(UIFont *)_font forState:(UIControlState)stateType;函数就是用来

设置图片以及文字共存的方法,用户可以通过传递 “left”,"top","right"参数来设置图标的显示位置。使用方法很简单,在我们添加UIButton的时候,调用该方法来进一步初始化按钮的显示。添加该方法后的显示效果如下:



我这边图省事,就全都使用了一个图标,当然界面还需要做的更加精细一些,在日后我会慢慢完善。

本文就到这吧,有什么错误的地方请大家指出来,谢啦!!!


0 0
原创粉丝点击