好久沒有更新部落格了,最近活比較忙,可能有3個禮拜沒有來更新部落格了。近期在做項目的時候,需求需要App中有一個可以控制視圖切換的控件,其實原理就是ios中的segment控件,但是sdk中的控件過于官方化,項目需要按照自己的設計圖來實作它。是以研究了一下自己寫了一個類似segment的控件,在這裡跟大家分享一下。ps:控件外觀還需要需改,這裡隻是将我實作的原理跟大家分享一下。
先看效果圖:
通過點選下面的控件來實作視圖的切換,目前的按鈕會更改外觀,而其他的按鈕則會恢複未點選的效果。
邏輯代碼如下:
//
// 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,類似微信的底端,如圖所示:
因為我們添加的都是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的時候,調用該方法來進一步初始化按鈕的顯示。添加該方法後的顯示效果如下:
我這邊圖省事,就全都使用了一個圖示,當然界面還需要做的更加精細一些,在日後我會慢慢完善。
本文就到這吧,有什麼錯誤的地方請大家指出來,謝啦!!!