`
jsntghf
  • 浏览: 2542438 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

自定义UISegmentedControl

    博客分类:
  • iOS
阅读更多

CustomSegmentedControl.h

 

@class CustomSegmentedControl;
@protocol CustomSegmentedControlDelegate

- (UIButton *) buttonFor:(CustomSegmentedControl *)segmentedControl atIndex:(NSUInteger)segmentIndex;

@optional
- (void) touchUpInsideSegmentIndex:(NSUInteger)segmentIndex;
- (void) touchDownAtSegmentIndex:(NSUInteger)segmentIndex;
@end

@interface CustomSegmentedControl : UIView {
    NSObject <CustomSegmentedControlDelegate> *delegate;
    NSMutableArray *buttons;
}

@property (nonatomic, retain) NSMutableArray *buttons;

- (id) initWithSegmentCount:(NSUInteger)segmentCount segmentsize:(CGSize)segmentsize dividerImage:(UIImage *)dividerImage tag:(NSInteger)objectTag delegate:(NSObject <CustomSegmentedControlDelegate> *)customSegmentedControlDelegate;

@end

 

CustomSegmentedControl.m

 

#import "CustomSegmentedControl.h"

@implementation CustomSegmentedControl
@synthesize buttons;

- (id) initWithSegmentCount:(NSUInteger)segmentCount segmentsize:(CGSize)segmentsize dividerImage:(UIImage *)dividerImage tag:(NSInteger)objectTag delegate:(NSObject <CustomSegmentedControlDelegate> *)customSegmentedControlDelegate {
    if (self = [super init]) {
        self.tag = objectTag;
        delegate = customSegmentedControlDelegate;
        self.frame = CGRectMake(0, 0, (segmentsize.width * segmentCount) + (dividerImage.size.width * (segmentCount - 1)), segmentsize.height);
        self.buttons = [[NSMutableArray alloc] initWithCapacity:segmentCount];
        CGFloat horizontalOffset = 0;
        for (NSUInteger i = 0; i < segmentCount; i++) {
            UIButton *button = [delegate buttonFor:self atIndex:i];
            [button addTarget:self action:@selector(touchDownAction:) forControlEvents:UIControlEventTouchDown];
            [button addTarget:self action:@selector(touchUpInsideAction:) forControlEvents:UIControlEventTouchUpInside];
            [button addTarget:self action:@selector(otherTouchesAction:) forControlEvents:UIControlEventTouchUpOutside];
            [button addTarget:self action:@selector(otherTouchesAction:) forControlEvents:UIControlEventTouchDragOutside];
            [button addTarget:self action:@selector(otherTouchesAction:) forControlEvents:UIControlEventTouchDragInside];
            [buttons addObject:button];
            button.frame = CGRectMake(horizontalOffset, 0.0, button.frame.size.width, button.frame.size.height);
            [self addSubview:button];
            
            if (i != segmentCount - 1) {
                UIImageView *divider = [[[UIImageView alloc] initWithImage:dividerImage] autorelease];
                divider.frame = CGRectMake(horizontalOffset + segmentsize.width, 0.0, dividerImage.size.width, dividerImage.size.height);
                [self addSubview:divider];
            }
            
            horizontalOffset = horizontalOffset + segmentsize.width + dividerImage.size.width;
        }
    }
    
    return self;
}

- (void) dimAllButtonsExcept:(UIButton *)selectedButton {
    for (UIButton *button in buttons) {
        if (button == selectedButton) {
            button.selected = YES;
            button.highlighted = button.selected ? NO : YES;
        } else {
            button.selected = NO;
            button.highlighted = NO;
        }
    }
}

- (void)touchDownAction:(UIButton *)button {
    [self dimAllButtonsExcept:button];
    
    if ([delegate respondsToSelector:@selector(touchDownAtSegmentIndex:)])
        [delegate touchDownAtSegmentIndex:[buttons indexOfObject:button]];
}

- (void)touchUpInsideAction:(UIButton *)button {
    [self dimAllButtonsExcept:button];
    
    if ([delegate respondsToSelector:@selector(touchUpInsideSegmentIndex:)])
        [delegate touchUpInsideSegmentIndex:[buttons indexOfObject:button]];
}

- (void)otherTouchesAction:(UIButton *)button {
    [self dimAllButtonsExcept:button];
}

- (void)dealloc {
    [buttons release];
    [super dealloc];
}

@end

 

CustomSegmentedControlsViewController.h

 

#import "CustomSegmentedControl.h"

@interface CustomSegmentedControlsViewController : UIViewController <CustomSegmentedControlDelegate> {

}

@end

 

CustomSegmentedControlsViewController.m

 

#import "CustomSegmentedControlsViewController.h"

#define VERTICAL_OFFSET 10.0
#define HORIZONTAL_OFFSET 10.0
#define VERTICAL_SPACING 5.0
#define VERTICAL_HEIGHT 70.0

#define TAG_VALUE 9000

static NSArray *buttons = nil;

typedef enum {
    CapLeft          = 0,
    CapMiddle        = 1,
    CapRight         = 2,
    CapLeftAndRight  = 3
} CapLocation;

@interface CustomSegmentedControlsViewController (PrivateMethods)
- (void) addView:(UIView *)subView verticalOffset:(NSUInteger)verticalOffset title:(NSString *)title;
@end

@implementation CustomSegmentedControlsViewController

- (void) awakeFromNib {
    buttons = [[NSArray arrayWithObjects:
                [NSDictionary dictionaryWithObjectsAndKeys:[NSArray arrayWithObjects:@"One", @"Two", @"Three", nil], @"titles", [NSValue valueWithCGSize:CGSizeMake(80, 47)], @"size", @"bottombarblue.png", @"button-image", @"bottombarblue_pressed.png", @"button-highlight-image", @"blue-divider.png", @"divider-image", [NSNumber numberWithFloat:14.0], @"cap-width", nil],
                [NSDictionary dictionaryWithObjectsAndKeys:[NSArray arrayWithObjects:@"One", @"Two", nil], @"titles", [NSValue valueWithCGSize:CGSizeMake(80, 47)], @"size", @"bottombarblue.png", @"button-image", @"bottombarblue_pressed.png", @"button-highlight-image", @"blue-divider.png", @"divider-image", [NSNumber numberWithFloat:14.0], @"cap-width", nil],
                [NSDictionary dictionaryWithObjectsAndKeys:[NSArray arrayWithObjects:@"One", @"Two", @"Three", nil], @"titles", [NSValue valueWithCGSize:CGSizeMake(100, 47)], @"size", @"bottombarredfire.png", @"button-image", @"bottombarredfire_pressed.png", @"button-highlight-image", @"red-divider.png", @"divider-image", [NSNumber numberWithFloat:14.0], @"cap-width", nil], 
                [NSDictionary dictionaryWithObjectsAndKeys:[NSArray arrayWithObjects:@"1", @"2", nil], @"titles", [NSValue valueWithCGSize:CGSizeMake(47, 47)], @"size", @"bottombarredfire.png", @"button-image", @"bottombarredfire_pressed.png", @"button-highlight-image", @"red-divider.png", @"divider-image", [NSNumber numberWithFloat:14.0], @"cap-width", nil], nil] retain];
}

- (void) viewDidLoad {
    [super viewDidLoad];
    
    NSDictionary *blueSegmentedControlData = [buttons objectAtIndex:0];
    NSArray *blueSegmentedControlTitles = [blueSegmentedControlData objectForKey:@"titles"];
    CustomSegmentedControl *blueSegmentedControl = [[[CustomSegmentedControl alloc] initWithSegmentCount:blueSegmentedControlTitles.count segmentsize:[[blueSegmentedControlData objectForKey:@"size"] CGSizeValue] dividerImage:[UIImage imageNamed:[blueSegmentedControlData objectForKey:@"divider-image"]] tag:TAG_VALUE delegate:self] autorelease];
    [self addView:blueSegmentedControl verticalOffset:0 title:@"Blue segmented control"];
    
    NSDictionary *anotherBlueSegmentedControlData = [buttons objectAtIndex:1];
    NSArray *anotherBlueSegmentedControlTitles = [anotherBlueSegmentedControlData objectForKey:@"titles"];
    CustomSegmentedControl *anotherBlueSegmentedControl = [[[CustomSegmentedControl alloc] initWithSegmentCount:anotherBlueSegmentedControlTitles.count segmentsize:[[anotherBlueSegmentedControlData objectForKey:@"size"] CGSizeValue] dividerImage:[UIImage imageNamed:[anotherBlueSegmentedControlData objectForKey:@"divider-image"]] tag:TAG_VALUE + 1 delegate:self] autorelease];
    [self addView:anotherBlueSegmentedControl verticalOffset:1 title:@"Another blue segmented control"];
    
    NSDictionary *redSegmentedControlData = [buttons objectAtIndex:2];
    NSArray *redSegmentedControlTitles = [redSegmentedControlData objectForKey:@"titles"];
    CustomSegmentedControl *redSegmentedControl = [[[CustomSegmentedControl alloc] initWithSegmentCount:redSegmentedControlTitles.count segmentsize:[[redSegmentedControlData objectForKey:@"size"] CGSizeValue] dividerImage:[UIImage imageNamed:[redSegmentedControlData objectForKey:@"divider-image"]] tag:TAG_VALUE + 2 delegate:self] autorelease];
    [self addView:redSegmentedControl verticalOffset:2 title:@"Red segmented control"];
    
    NSDictionary *anotherRedSegmentedControlData = [buttons objectAtIndex:3];
    NSArray *anotherRedSegmentedControlTitles = [anotherRedSegmentedControlData objectForKey:@"titles"];
    CustomSegmentedControl *anotherRedSegmentedControl = [[[CustomSegmentedControl alloc] initWithSegmentCount:anotherRedSegmentedControlTitles.count segmentsize:[[anotherRedSegmentedControlData objectForKey:@"size"] CGSizeValue] dividerImage:[UIImage imageNamed:[anotherRedSegmentedControlData objectForKey:@"divider-image"]] tag:TAG_VALUE + 3 delegate:self] autorelease];
    [self addView:anotherRedSegmentedControl verticalOffset:3 title:@"Another red segmented control"];
}

- (void) addView:(UIView *)subView verticalOffset:(NSUInteger)verticalOffset title:(NSString *)title {
    CGFloat elementVerticalLocation = (VERTICAL_HEIGHT + (VERTICAL_SPACING * 2)) * verticalOffset;
    
    UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(HORIZONTAL_OFFSET, elementVerticalLocation + VERTICAL_OFFSET, 0, 0)] autorelease];
    label.backgroundColor = [UIColor clearColor];
    label.textColor = [UIColor whiteColor];
    label.text = title;
    [label sizeToFit];
    
    [self.view addSubview:label];
    
    subView.frame = CGRectMake(HORIZONTAL_OFFSET, elementVerticalLocation + label.frame.size.height + 5 + VERTICAL_OFFSET, subView.frame.size.width, subView.frame.size.height);
    [self.view addSubview:subView];
}

- (UIImage *) image:(UIImage *)image withCap:(CapLocation)location capWidth:(NSUInteger)capWidth buttonWidth:(NSUInteger)buttonWidth {
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(buttonWidth, image.size.height), NO, 0.0);
    
    if (location == CapLeft)
        [image drawInRect:CGRectMake(0, 0, buttonWidth + capWidth, image.size.height)];
    else if (location == CapRight)
        [image drawInRect:CGRectMake(0.0 - capWidth, 0, buttonWidth + capWidth, image.size.height)];
    else if (location == CapMiddle)
        [image drawInRect:CGRectMake(0.0 - capWidth, 0, buttonWidth + (capWidth * 2), image.size.height)];
    
    UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return resultImage;
}

#pragma mark -
#pragma mark CustomSegmentedControlDelegate
- (UIButton *) buttonFor:(CustomSegmentedControl *)segmentedControl atIndex:(NSUInteger)segmentIndex {
    NSUInteger dataOffset = segmentedControl.tag - TAG_VALUE ;
    NSDictionary *data = [buttons objectAtIndex:dataOffset];
    NSArray *titles = [data objectForKey:@"titles"];
    
    CapLocation location;
    if (segmentIndex == 0)
        location = CapLeft;
    else if (segmentIndex == titles.count - 1)
        location = CapRight;
    else
        location = CapMiddle;
    
    UIImage *buttonImage = nil;
    UIImage *buttonPressedImage = nil;
    
    CGFloat capWidth = [[data objectForKey:@"cap-width"] floatValue];
    CGSize buttonSize = [[data objectForKey:@"size"] CGSizeValue];
    
    if (location == CapLeftAndRight) {
        buttonImage = [[UIImage imageNamed:[data objectForKey:@"button-image"]] stretchableImageWithLeftCapWidth:capWidth topCapHeight:0.0];
        buttonPressedImage = [[UIImage imageNamed:[data objectForKey:@"button-highlight-image"]] stretchableImageWithLeftCapWidth:capWidth topCapHeight:0.0];
    } else {
        buttonImage = [self image:[[UIImage imageNamed:[data objectForKey:@"button-image"]] stretchableImageWithLeftCapWidth:capWidth topCapHeight:0.0] withCap:location capWidth:capWidth buttonWidth:buttonSize.width];
        buttonPressedImage = [self image:[[UIImage imageNamed:[data objectForKey:@"button-highlight-image"]] stretchableImageWithLeftCapWidth:capWidth topCapHeight:0.0] withCap:location capWidth:capWidth buttonWidth:buttonSize.width];
    }
    
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(0.0, 0.0, buttonSize.width, buttonSize.height);
    
    [button setTitle:[titles objectAtIndex:segmentIndex] forState:UIControlStateNormal];
    [button setBackgroundImage:buttonImage forState:UIControlStateNormal];
    [button setBackgroundImage:buttonPressedImage forState:UIControlStateHighlighted];
    [button setBackgroundImage:buttonPressedImage forState:UIControlStateSelected];
    button.adjustsImageWhenHighlighted = NO;
    
    if (segmentIndex == 0)
        button.selected = YES;
    return button;
}

@end

 

效果图:


分享到:
评论

相关推荐

    ios-自定义UISegmentedControl.zip

    这个压缩包"ios-自定义UISegmentedControl.zip"提供了对系统默认`UISegmentedControl`的一个自定义实现,以满足开发者对于界面样式和交互的个性化需求。源代码来源于GitHub项目 `STKitSwift`,作者是STShenZhaoliang...

    自定义UISegmentedControl控件

    本教程将深入探讨如何自定义UISegmentedControl,以实现独特的视觉效果和交互体验。 首先,我们要理解UISegmentedControl的基本结构。它由一个或多个段组成,每个段可以包含文本或图像。默认情况下,用户点击某个段...

    自定义UISegmentedControl iOS

    然而,系统默认的UISegmentedControl样式有时不能满足设计师和开发者的需求,这时就需要自定义UISegmentedControl来实现特定的设计效果。本文将围绕STShenZhaoliang的作品——STKitSwift,详细讲解如何自定义...

    swift-采用Swift编写自定义UISegmentedControl实现的滑块Tab效果

    然而,系统默认的样式有时无法满足设计师的个性化需求,因此开发者经常需要自定义`UISegmentedControl`来实现特定的视觉效果。本教程将深入探讨如何使用Swift语言创建一个具有滑块Tab效果的自定义`...

    SegView.zip

    首先,我们来看一下如何自定义UISegmentedControl的布局方向。默认情况下,UISegmentedControl是水平排列的,如果想要将其设置为垂直布局,我们需要通过自定义视图和布局约束来实现。可以创建一个新的继承自...

    IOS应用源码——自定义颜色的UISegmentedControl.zip

    这个压缩包"IOS应用源码——自定义颜色的UISegmentedControl.zip"提供了一个示例,展示了如何自定义UISegmentedControl的颜色,使得UI设计更加个性化。下面我们将详细讨论关于自定义UISegmentedControl颜色的相关...

    IOS应用源码Demo-自定义颜色的UISegmentedControl-毕设学习.zip

    这个Demo的重点在于如何自定义UISegmentedControl的颜色,这涉及到以下几个方面: 1. **自定义颜色**: 开发者可以通过设置`setTitleTextAttributes:`方法来改变UISegmentedControl的文字颜色,以及通过`...

    IOS应用源码——自定义颜色的UISegmentedControl.rar

    下面我们将深入探讨这个主题,以及在iOS开发中自定义UISegmentedControl的相关知识点。 首先,我们要了解UISegmentedControl的基本用法。它通常用于展示两个或更多的操作选项,每个选项对应一个段。默认情况下,每...

    IOS应用源码之自定义颜色的UISegmentedControl.zip

    本资源“IOS应用源码之自定义颜色的UISegmentedControl.zip”提供了关于如何自定义UISegmentedControl颜色的示例代码,这对于那些希望使应用界面更加个性化和吸引用户注意力的开发者来说是十分有价值的。 首先,...

    利用 UISegmentedControl 实现的滑块儿 Tab 效果.zip

    "利用 UISegmentedControl 实现的滑块儿 Tab 效果.zip"这个开源项目就是为了解决这一需求,它通过自定义UISegmentedControl来实现这种滑动切换的效果,整个项目是用Swift编程语言编写的。 首先,让我们深入理解...

    ios应用源码之自定义颜色的uisegmentedcontrol 20181210

    本文将深入探讨如何在2018年12月10日的iOS应用源码中自定义`UISegmentedControl`的颜色,以实现独特的视觉效果。 首先,了解`UISegmentedControl`的基本概念。它是`UIKit`框架的一部分,通常用于展示一组相关的开关...

    自定义UISegmentController

    自定义UISegmentedControl涉及到以下几个关键知识点: 1. **初始化与配置**:首先,你需要创建一个UISegmentedControl实例,通过初始化方法如`initWithItems:`传入标题数组来设置各个段的标签。你可以调整其大小、...

    IOS应用源码之自定义颜色的UISegmentedControl .rar

    这个源码示例"自定义颜色的UISegmentedControl"着重于如何根据开发者的需求,对默认的`UISegmentedControl`外观进行个性化定制,特别是颜色方面。在iOS开发中,自定义UI元素是提升应用视觉效果和用户体验的关键。 `...

    IOS类似网易新闻的segment切换

    要实现与网易新闻类似的segment切换效果,可能需要进一步自定义UISegmentedControl的样式,例如添加边框、圆角、分割线等。可以使用`layer`属性来设置边框和圆角,使用自定义图像来模拟分割线。同时,可以监听`...

    自定义颜色的UISegmentedControl.zipIOS应用例子源码下载

    自定义颜色的UISegmentedControl.zipIOS应用例子源码下载自定义颜色的UISegmentedControl.zipIOS应用例子源码下载 1.适合学生学习研究参考 2.适合个人学习研究参考 3.适合公司开发项目技术参考

    ios 连带滚动

    综上所述,实现"ios 连带滚动"涉及到自定义UISegmentedControl,动态计算下划线长度,设计可配置的接口,以及与内容视图的联动滚动逻辑。通过这一系列步骤,我们可以创建一个高效且用户友好的交互组件。

    ios-仿制安卓ObservableScrollView.zip

    开发者可能通过自定义UISegmentedControl或者使用第三方库如SWRevealViewController,与UIScrollView相结合,实现了滑动手势切换不同内容的视图。 此外,"图文混排"这一标签表明项目可能包含复杂的布局管理,特别是...

    UISegmentedControl

    5. **自定义外观**:可以使用`appearance` API来自定义所有`UISegmentedControl`的外观,或者针对特定实例使用`setTitleTextAttributes:forState:`来改变文字样式,`setDividerImage:forLeftSegmentState:...

    UISegmentedControl Demo代码

    在给定的"UISegmentedControl Demo代码"中,我们可以期待看到如何在实践中创建和自定义`UISegmentedControl`的例子。 首先,`UISegmentedControl`的基本用法包括初始化控件并添加按钮。在Objective-C或Swift中,你...

Global site tag (gtag.js) - Google Analytics