天天看点

iOS开发之自定义segment实现视图切换

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

先看效果图:

iOS开发之自定义segment实现视图切换
iOS开发之自定义segment实现视图切换

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

逻辑代码如下:

//
//  CustomSegmentView.h
//  PanderStrategy
//
//  Created by silicon on 14-9-2.
//  Copyright (c) 2014年 silicon. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "UIButton+Icon.h"

@protocol CustomDelegate <NSObject>

- (void)buttonClick:(NSInteger)sender;

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

@end


@interface CustomSegmentView : UIView

@property (nonatomic, strong) UIColor *cusBkColor;
@property (nonatomic, strong) UIColor *cusSelColor;
@property (nonatomic, strong) NSMutableArray *segmentArray;
@property (nonatomic, strong) UIColor *cusTextColor;
@property (assign) float cusbWidth;
@property (nonatomic, strong) UIColor *cusbColor;
@property (strong, nonatomic) id<CustomDelegate>myDelagte;


- (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;

//- (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;





@end
           

实现文件:

//
//  CustomSegmentView.m
//  PanderStrategy
//
//  Created by silicon on 14-9-2.
//  Copyright (c) 2014年 silicon. All rights reserved.
//

#import "CustomSegmentView.h"

@implementation CustomSegmentView
@synthesize cusBkColor = _cusBkColor;
@synthesize cusSelColor = _cusSelColor;
@synthesize segmentArray = _segmentArray;
@synthesize cusTextColor = _cusTextColor;

- (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
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        [self setBackgroundColor:_bkColor];
        self.cusBkColor = _bkColor;
        self.cusSelColor = _selColor;
        self.cusTextColor = _textColor;
        self.cusbWidth = _bWidth;
        self.cusbColor = _bColor;
        
        self.segmentArray = [[NSMutableArray alloc] init];
        
        float width = frame.size.width/_array.count;
        for (int i = 0; i < [_array count]; i++) {
            UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(width * i, 0, width, frame.size.height)];
//            [btn setImageWithTitle:[UIImage imageNamed:@"email"] withTitle:[_array objectAtIndex:i] position:@"right" font:_font forState:UIControlStateNormal];
            
            //不需要图片与文字一起显示
            [btn setTitle:[_array objectAtIndex:i] forState:UIControlStateNormal];
            [btn setFont:_font];
            
            [btn addTarget:self action:@selector(clickSegment:) forControlEvents:UIControlEventTouchUpInside];
            
            [_segmentArray addObject:btn];
            [self addSubview:btn];
        }
        self.layer.masksToBounds=YES;
    }
    return self;
}


//- (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{
//    self = [super initWithFrame:frame];
//    if (self) {
//        // Initialization code
//        [self setBackgroundColor:_bkColor];
//        self.cusBkColor = _bkColor;
//        self.cusSelColor = _selColor;
//        self.cusTextColor = _textColor;
//        self.cusbWidth = _bWidth;
//        self.cusbColor = _bColor;
//        
//        self.segmentArray = [[NSMutableArray alloc] init];
//        
//        float width = frame.size.width/_array.count;
//        for (int i = 0; i < [_array count]; i++) {
//            UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(width * i, 0, width, frame.size.height)];
//            [btn setTitle:[_array objectAtIndex:i] forState:UIControlStateNormal];
//            [btn setFont:_font];
//            [btn addTarget:self action:@selector(clickOtherSegment:) forControlEvents:UIControlEventTouchUpInside];
//            
//            [_segmentArray addObject:btn];
//            [self addSubview:btn];
//        }
//        self.layer.masksToBounds=YES;
//    }
//    return self;
//}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code
}
*/

- (void)clickSegment:(id)sender{
    UIButton *btn = (UIButton *)sender;
    NSUInteger index = [_segmentArray indexOfObject:btn];
    
    [self.myDelagte buttonClick:index];
    [self updateSegmentStates:index];
    
}

//- (void)clickOtherSegment:(id)sender{
//    UIButton *btn = (UIButton *)sender;
//    NSUInteger index = [_segmentArray indexOfObject:btn];
//    
//    [self.myDelagte topButtonClick:btn.titleLabel.text];
//    [self updateSegmentStates:index];
//}

- (void)updateSegmentStates:(NSUInteger )index{
    self.layer.borderWidth=self.cusbWidth;
    self.layer.borderColor=self.cusbColor.CGColor;
    
    for (int i = 0; i < [_segmentArray count]; i++) {
        if(i == index){
            UIButton *btn = [_segmentArray objectAtIndex:index];
            [btn setBackgroundColor:_cusSelColor];
            [btn setTitleColor:_cusTextColor forState:UIControlStateNormal];
        }else{
            UIButton *btn = [_segmentArray objectAtIndex:i];
            [btn setBackgroundColor:_cusBkColor];
            [btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        }
    }
}
@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,类似微信的底端,如图所示:

iOS开发之自定义segment实现视图切换

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

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

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

#import <Foundation/Foundation.h>

@interface UIButton (CustomBtn)

- (void)setImageWithTitle:(UIImage *)image withTitle:(NSString *)title position:(NSString *)_position font:(UIFont *)_font forState:(UIControlState)stateType;

@end
           
#import "UIButton+Icon.h"

@implementation UIButton (CustomBtn)

- (void)setImageWithTitle:(UIImage *)image withTitle:(NSString *)title position:(NSString *)_position font:(UIFont *)_font forState:(UIControlState)stateType{
    CGSize titleSize = [title sizeWithFont:[UIFont systemFontOfSize:11.0f]];
    [self.imageView setContentMode:UIViewContentModeCenter];
    
    if([_position isEqualToString:@"left"]){
        [self setImageEdgeInsets:UIEdgeInsetsMake((self.frame.size.height - 50)/2, 10.0, 0.0, 0)];
    }else if([_position isEqualToString:@"top"]){
        [self setImageEdgeInsets:UIEdgeInsetsMake(5.0, 0.0, 20.0, -titleSize.width)];
    }else if([_position isEqualToString:@"right"]){
        [self setImageEdgeInsets:UIEdgeInsetsMake((self.frame.size.height - 50)/2, titleSize.width + 25, 0.0, 0.0)];
    }

    
    [self setImage:image forState:stateType];
    
    [self.titleLabel setContentMode:UIViewContentModeCenter];
    [self.titleLabel setBackgroundColor:[UIColor clearColor]];
    [self.titleLabel setFont:_font];
    
    if([_position isEqualToString:@"left"]){
        [self setTitleEdgeInsets:UIEdgeInsetsMake((self.frame.size.height - 50)/2,
                                                  image.size.width,
                                                  0.0,
                                                  0.0)];
    }else if([_position isEqualToString:@"top"]){
        [self setTitleEdgeInsets:UIEdgeInsetsMake(30.0,
                                                  -image.size.width,
                                                  0.0,
                                                  0.0)];
    }else if([_position isEqualToString:@"right"]){
        [self setTitleEdgeInsets:UIEdgeInsetsMake((self.frame.size.height - 50)/2,
                                                  -40.0,
                                                  0.0,
                                                  0)];
    }
    
    
    [self setTitle:title forState:stateType];
}

@end
           

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

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

iOS开发之自定义segment实现视图切换
iOS开发之自定义segment实现视图切换
iOS开发之自定义segment实现视图切换

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

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