iOS开发-实现热门话题标签tag显示控件

iOS开发-实现热门话题标签tag显示控件

话题标签tag显示非常常见,如选择你的兴趣,选择关注的群,超话,话题等等。

一、效果图

二、实现代码

由于显示的是在列表中,这里整体控件是放在UITableViewCell中的。

2.1 标签tag按钮实现

自定义标签tag按钮INRmdTopicButton

INRmdTopicButton.h

objectivec 复制代码
@interface INRmdTopicButton : UIControl

@property (nonatomic, strong) NSString *topicName;
@property (nonatomic, assign) CGFloat showTopicWidth;

+ (CGFloat)topicWidth:(NSString *)name;

@end

INRmdTopicButton.m

objectivec 复制代码
@interface INRmdTopicButton ()

@property (nonatomic, strong) UIImageView *backImageView;       //图片控件
@property (nonatomic, strong) UIImageView *tbkImageView;       //图片控件
@property (nonatomic, strong) UILabel *titleLabel;

@end

@implementation INRmdTopicButton

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self addSubview:self.backImageView];
        [self.backImageView addSubview:self.tbkImageView];
        [self.backImageView addSubview:self.titleLabel];
    }
    return self;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    self.backImageView.frame = self.bounds;
    self.tbkImageView.frame = CGRectMake(0.0, 0.0, CGRectGetWidth(self.backImageView.frame), CGRectGetHeight(self.backImageView.frame) - kSmallPadding);
    self.titleLabel.frame = CGRectMake(0.0, 0.0, CGRectGetWidth(self.backImageView.frame), kTopicNameHeight);
}

- (void)setTopicName:(NSString *)topicName {
    _topicName = (topicName?topicName:@"");
    self.titleLabel.text = _topicName;
    [self setNeedsLayout];
}

+ (CGFloat)topicWidth:(NSString *)name {
    CGSize topicSize = [name sizeWithFont:[UIFont systemFontOfSize:12] forMaxSize:CGSizeMake(MAXFLOAT, kTopicHeight)];
    return topicSize.width + 2*kSmallPadding;
}

#pragma mark - SETTER/GETTER
- (UIImageView *)backImageView {
    if (!_backImageView) {
        _backImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
        _backImageView.userInteractionEnabled = YES;
        _backImageView.backgroundColor = [UIColor clearColor];
    }
    return _backImageView;
}

- (UIImageView *)tbkImageView {
    if (!_tbkImageView) {
        _tbkImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
        _tbkImageView.userInteractionEnabled = YES;
        _tbkImageView.backgroundColor = [UIColor clearColor];
        UIImage *image = [UIImage imageNamed:@"bk_topic_r"];
        image = [image stretchableImageWithLeftCapWidth:floorf(image.size.width * 0.5) topCapHeight:floorf(image.size.height * 0.5)];
        _tbkImageView.image = image;
    }
    return _tbkImageView;
}

- (UILabel *)titleLabel {
    if (!_titleLabel) {
        _titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        _titleLabel.font = [UIFont systemFontOfSize:12];
        _titleLabel.textAlignment = NSTextAlignmentCenter;
        _titleLabel.textColor = [UIColor colorWithHexString:@"555555"];
        _titleLabel.backgroundColor = [UIColor clearColor];
    }
    return _titleLabel;
}

@end

2.2 显示排列标签tag

显示标题tag时候,需要排列按钮

objectivec 复制代码
INRmdTopicButton *lastButton = nil;
    for (UIView *subView in self.topicBKImageView.subviews) {
        if ([subView isKindOfClass:[INRmdTopicButton class]]) {
            INRmdTopicButton *button = (INRmdTopicButton *)subView;
            button.hidden = NO;
            if (lastButton) {
                if (CGRectGetMaxX(lastButton.frame) + button.showTopicWidth + kSmallPadding > maxWidth) {
                    button.frame = CGRectMake(0.0, CGRectGetMaxY(lastButton.frame), button.showTopicWidth, kTopicHeight);
                } else {
                    button.frame = CGRectMake(CGRectGetMaxX(lastButton.frame) + kSmallPadding, CGRectGetMinY(lastButton.frame), button.showTopicWidth, kTopicHeight);
                }
            } else {
                button.frame = CGRectMake(originX, originY, button.showTopicWidth, kTopicHeight);
            }
            
            if (CGRectGetMaxY(button.frame) > maxHeight) {
                button.hidden = YES;
            } else {
                button.hidden = NO;
            }
            
            lastButton = button;
        }
    }

这里还加了拖动手势UIPanGestureRecognizer,当往左拖动的时候会显示松开换一换的功能。调用接口实现。

objectivec 复制代码
#pragma mark - panGestureHandle
- (void)panGestureHandle:(UIPanGestureRecognizer *)pan{
    if (pan.state == UIGestureRecognizerStateBegan) {
        NSLog(@"UIGestureRecognizerStateBegan");
        self.startPoint = [pan translationInView:self];
    } if (pan.state == UIGestureRecognizerStateChanged) {
        NSLog(@"UIGestureRecognizerStateChanged");
        
        CGPoint point = [pan translationInView:self];
        CGFloat xDistance = point.x - self.startPoint.x;
        // 左右滑动
        NSLog(@"左右滑动");
        if (xDistance > 0) {
            NSLog(@"向右滑动");
            CGRect backFrame = self.topicBKImageView.frame;
            backFrame.origin.x = kMidPadding;
            self.topicBKImageView.frame = backFrame;
        } else {
            NSLog(@"向左滑动");
            CGRect backFrame = self.topicBKImageView.frame;
            backFrame.origin.x = kMidPadding + xDistance*0.5;
            self.topicBKImageView.frame = backFrame;
        }
        
    } else {
        // if (pan.state == UIGestureRecognizerStateEnded || pan.state == UIGestureRecognizerStateCancelled || pan.state == UIGestureRecognizerStateFailed)
        NSLog(@"UIGestureRecognizerStateEnded");
        CGRect backFrame = self.topicBKImageView.frame;
        backFrame.origin.x = kMidPadding;
        [UIView animateWithDuration:0.55 delay:0.0 usingSpringWithDamping:0.5 initialSpringVelocity:7.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
            self.topicBKImageView.frame = backFrame;
        } completion:^(BOOL finished) {
            
        }];
    }
}

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

2.3 完整代码如下

INRecommentTopicCell.h

objectivec 复制代码
#import <UIKit/UIKit.h>

@interface INRmdTopicButton : UIControl

@property (nonatomic, strong) NSString *topicName;
@property (nonatomic, assign) CGFloat showTopicWidth;

+ (CGFloat)topicWidth:(NSString *)name;

@end

/**
 推荐的话题
 */
@interface INRecommentTopicCell : UITableViewCell

+ (CGFloat)cellHeight;

@end

INRecommentTopicCell.m

objectivec 复制代码
#import "INRecommentTopicCell.h"
#import "UIColor+Addition.h"
#import "NSString+Size.h"

static CGFloat kCellHeight = 260.0;

static CGFloat kCellHorBGPadding = 10.0f;
static CGFloat kCellVerBGPadding = 5.0f;

static CGFloat kTitleHeight = 44.0f;
static CGFloat kMidPadding = 10.0f;

static CGFloat kSmallPadding = 5.0f;
static CGFloat kTopicHeight = 40.0f;
static CGFloat kTopicNameHeight = 30.0f;

static CGFloat kExchangeBtnSize = 40.0f;
static CGFloat kTisWidth = 20.0f;

@interface INRmdTopicButton ()

@property (nonatomic, strong) UIImageView *backImageView;       //图片控件
@property (nonatomic, strong) UIImageView *tbkImageView;       //图片控件
@property (nonatomic, strong) UILabel *titleLabel;

@end

@implementation INRmdTopicButton

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self addSubview:self.backImageView];
        [self.backImageView addSubview:self.tbkImageView];
        [self.backImageView addSubview:self.titleLabel];
    }
    return self;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    self.backImageView.frame = self.bounds;
    self.tbkImageView.frame = CGRectMake(0.0, 0.0, CGRectGetWidth(self.backImageView.frame), CGRectGetHeight(self.backImageView.frame) - kSmallPadding);
    self.titleLabel.frame = CGRectMake(0.0, 0.0, CGRectGetWidth(self.backImageView.frame), kTopicNameHeight);
}

- (void)setTopicName:(NSString *)topicName {
    _topicName = (topicName?topicName:@"");
    self.titleLabel.text = _topicName;
    [self setNeedsLayout];
}

+ (CGFloat)topicWidth:(NSString *)name {
    CGSize topicSize = [name sizeWithFont:[UIFont systemFontOfSize:12] forMaxSize:CGSizeMake(MAXFLOAT, kTopicHeight)];
    return topicSize.width + 2*kSmallPadding;
}

#pragma mark - SETTER/GETTER
- (UIImageView *)backImageView {
    if (!_backImageView) {
        _backImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
        _backImageView.userInteractionEnabled = YES;
        _backImageView.backgroundColor = [UIColor clearColor];
    }
    return _backImageView;
}

- (UIImageView *)tbkImageView {
    if (!_tbkImageView) {
        _tbkImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
        _tbkImageView.userInteractionEnabled = YES;
        _tbkImageView.backgroundColor = [UIColor clearColor];
        UIImage *image = [UIImage imageNamed:@"bk_topic_r"];
        image = [image stretchableImageWithLeftCapWidth:floorf(image.size.width * 0.5) topCapHeight:floorf(image.size.height * 0.5)];
        _tbkImageView.image = image;
    }
    return _tbkImageView;
}

- (UILabel *)titleLabel {
    if (!_titleLabel) {
        _titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        _titleLabel.font = [UIFont systemFontOfSize:12];
        _titleLabel.textAlignment = NSTextAlignmentCenter;
        _titleLabel.textColor = [UIColor colorWithHexString:@"555555"];
        _titleLabel.backgroundColor = [UIColor clearColor];
    }
    return _titleLabel;
}

@end

/**
 推荐的话题
 */
@interface INRecommentTopicCell ()

@property (nonatomic, strong) UIImageView *backImageView;       //图片控件
@property (nonatomic, strong) UIImageView *contentBGImageView;       //图片控件
@property (nonatomic, strong) UIImageView *topicBKImageView;       //图片控件
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UIButton *exchangeButton;     // 更多

@property (nonatomic, strong) UILabel *tipsLabel;

@property (nonatomic) CGPoint startPoint;     // 开始点

@end

@implementation INRecommentTopicCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code
        
        self.backgroundColor = [UIColor clearColor];
        self.contentView.backgroundColor = [UIColor clearColor];
        [self.contentView addSubview:self.backImageView];
        [self.contentView addSubview:self.contentBGImageView];
        [self.contentBGImageView addSubview:self.titleLabel];
        [self.contentBGImageView addSubview:self.exchangeButton];
        [self.contentBGImageView addSubview:self.tipsLabel];
        [self.contentBGImageView addSubview:self.topicBKImageView];

        [self setupRmdTopicViews];
        
        UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panGestureHandle:)];
        panGesture.minimumNumberOfTouches = 1;
        panGesture.maximumNumberOfTouches = 1;
        panGesture.delegate = self;
        [self.contentBGImageView addGestureRecognizer:panGesture];
    }
    return self;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    self.backImageView.frame = CGRectMake(kCellHorBGPadding, kCellVerBGPadding, CGRectGetWidth(self.bounds) - 2*kCellHorBGPadding, CGRectGetHeight(self.bounds) - 2*kCellVerBGPadding);
    
    self.contentBGImageView.frame = CGRectMake(kCellHorBGPadding, kCellVerBGPadding, CGRectGetWidth(self.bounds) - 2*kCellHorBGPadding, CGRectGetHeight(self.bounds) - 2*kCellVerBGPadding);

    self.titleLabel.frame = CGRectMake(kMidPadding, 0.0, CGRectGetWidth(self.backImageView.frame) - 3*kMidPadding - kExchangeBtnSize, kTitleHeight);
    
    self.exchangeButton.frame = CGRectMake(CGRectGetWidth(self.backImageView.frame) - kMidPadding - kExchangeBtnSize, (kTitleHeight - kExchangeBtnSize)/2, kExchangeBtnSize, kExchangeBtnSize);
    
    CGFloat height = CGRectGetHeight(self.backImageView.frame) - CGRectGetMaxY(self.titleLabel.frame);
    self.tipsLabel.frame = CGRectMake(CGRectGetWidth(self.backImageView.frame) - kMidPadding - kTisWidth, 0.0, kTisWidth, height);
    
    self.topicBKImageView.frame = CGRectMake(kMidPadding, CGRectGetMaxY(self.titleLabel.frame), CGRectGetWidth(self.backImageView.frame) - 2*kMidPadding, height);
    
    CGFloat maxWidth = CGRectGetWidth(self.topicBKImageView.frame);
    CGFloat maxHeight = CGRectGetHeight(self.topicBKImageView.frame);
    
    CGFloat originX = 0.0;
    CGFloat originY = 0.0;

    INRmdTopicButton *lastButton = nil;
    for (UIView *subView in self.topicBKImageView.subviews) {
        if ([subView isKindOfClass:[INRmdTopicButton class]]) {
            INRmdTopicButton *button = (INRmdTopicButton *)subView;
            button.hidden = NO;
            if (lastButton) {
                if (CGRectGetMaxX(lastButton.frame) + button.showTopicWidth + kSmallPadding > maxWidth) {
                    button.frame = CGRectMake(0.0, CGRectGetMaxY(lastButton.frame), button.showTopicWidth, kTopicHeight);
                } else {
                    button.frame = CGRectMake(CGRectGetMaxX(lastButton.frame) + kSmallPadding, CGRectGetMinY(lastButton.frame), button.showTopicWidth, kTopicHeight);
                }
            } else {
                button.frame = CGRectMake(originX, originY, button.showTopicWidth, kTopicHeight);
            }
            
            if (CGRectGetMaxY(button.frame) > maxHeight) {
                button.hidden = YES;
            } else {
                button.hidden = NO;
            }
            
            lastButton = button;
        }
    }
}

- (void)setupRmdTopicViews {
    for (UIView *subView in self.topicBKImageView.subviews) {
        if ([subView isKindOfClass:[INRmdTopicButton class]]) {
            [subView removeFromSuperview];
        }
    }
    
    for (NSInteger index = 0; index < 15; index ++) {
        INRmdTopicButton *button = [[INRmdTopicButton alloc] initWithFrame:CGRectZero];
        button.tag = index;
        [self.topicBKImageView addSubview:button];
        
        if (index % 5 == 0) {
            button.topicName = @"#读书交流";
        } else if (index % 5 == 1) {
            button.topicName = @"#爱手工生活";
        } else if (index % 5 == 2) {
            button.topicName = @"#精致的佛系生活";
        } else if (index % 5 == 3) {
            button.topicName = @"#数码发烧友";
        } else if (index % 5 == 4) {
            button.topicName = @"#晒晒你的心情";
        } else {
            button.topicName = @"#说说身边事";
        }
        button.showTopicWidth = [INRmdTopicButton topicWidth:button.topicName];
    }
    
    [self setNeedsLayout];
}


- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

+ (CGFloat)cellHeight {
    return kCellHeight;
}

#pragma mark - Actions
- (void)exchangeButtonAction {
    
}

#pragma mark - SETTER/GETTER
- (UIImageView *)backImageView {
    if (!_backImageView) {
        _backImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
        _backImageView.userInteractionEnabled = YES;
        _backImageView.backgroundColor = [UIColor whiteColor];
        _backImageView.layer.cornerRadius = 2.0;
        _backImageView.layer.shadowColor = [UIColor colorWithHexString:@"9bb9ef"].CGColor;
        _backImageView.layer.shadowOffset = CGSizeMake(0, 3);
        _backImageView.layer.shadowOpacity = 0.3;
        _backImageView.layer.shadowRadius = 3.0;
    }
    return _backImageView;
}

- (UIImageView *)contentBGImageView {
    if (!_contentBGImageView) {
        _contentBGImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
        _contentBGImageView.userInteractionEnabled = YES;
        _contentBGImageView.backgroundColor = [UIColor whiteColor];
        _contentBGImageView.layer.cornerRadius = 2.0;
        _contentBGImageView.layer.masksToBounds = YES;
        _contentBGImageView.clipsToBounds = YES;
    }
    return _contentBGImageView;
}

- (UIImageView *)topicBKImageView {
    if (!_topicBKImageView) {
        _topicBKImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
        _topicBKImageView.userInteractionEnabled = YES;
        _topicBKImageView.backgroundColor = [UIColor whiteColor];
        _topicBKImageView.clipsToBounds = YES;
    }
    return _topicBKImageView;
}

- (UILabel *)titleLabel {
    if (!_titleLabel) {
        _titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        _titleLabel.font = [UIFont systemFontOfSize:18];
        _titleLabel.textColor = [UIColor colorWithHexString:@"131619"];
        _titleLabel.backgroundColor = [UIColor clearColor];
        _titleLabel.text = @"热门话题";
    }
    return _titleLabel;
}

- (UILabel *)tipsLabel {
    if (!_tipsLabel) {
        _tipsLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        _tipsLabel.font = [UIFont systemFontOfSize:12];
        _tipsLabel.textColor = [UIColor colorWithHexString:@"9a9b9c"];
        _tipsLabel.backgroundColor = [UIColor clearColor];
        _tipsLabel.numberOfLines = 0;
        _tipsLabel.textAlignment = NSTextAlignmentCenter;
        _tipsLabel.text = @"松\n开\n换\n一\n换";
    }
    return _tipsLabel;
}

- (UIButton *)exchangeButton {
    if (!_exchangeButton) {
        _exchangeButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [_exchangeButton setImage:[UIImage imageNamed:@"ic_topic_exchange"] forState:UIControlStateNormal];
        [_exchangeButton addTarget:self action:@selector(exchangeButtonAction) forControlEvents:UIControlEventTouchUpInside];
    }
    return _exchangeButton;
}

#pragma mark - panGestureHandle
- (void)panGestureHandle:(UIPanGestureRecognizer *)pan{
    if (pan.state == UIGestureRecognizerStateBegan) {
        NSLog(@"UIGestureRecognizerStateBegan");
        self.startPoint = [pan translationInView:self];
    } if (pan.state == UIGestureRecognizerStateChanged) {
        NSLog(@"UIGestureRecognizerStateChanged");
        
        CGPoint point = [pan translationInView:self];
        CGFloat xDistance = point.x - self.startPoint.x;
        // 左右滑动
        NSLog(@"左右滑动");
        if (xDistance > 0) {
            NSLog(@"向右滑动");
            CGRect backFrame = self.topicBKImageView.frame;
            backFrame.origin.x = kMidPadding;
            self.topicBKImageView.frame = backFrame;
        } else {
            NSLog(@"向左滑动");
            CGRect backFrame = self.topicBKImageView.frame;
            backFrame.origin.x = kMidPadding + xDistance*0.5;
            self.topicBKImageView.frame = backFrame;
        }
        
    } else {
        // if (pan.state == UIGestureRecognizerStateEnded || pan.state == UIGestureRecognizerStateCancelled || pan.state == UIGestureRecognizerStateFailed)
        NSLog(@"UIGestureRecognizerStateEnded");
        CGRect backFrame = self.topicBKImageView.frame;
        backFrame.origin.x = kMidPadding;
        [UIView animateWithDuration:0.55 delay:0.0 usingSpringWithDamping:0.5 initialSpringVelocity:7.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
            self.topicBKImageView.frame = backFrame;
        } completion:^(BOOL finished) {
            
        }];
    }
}

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

@end

三、小结

iOS开发-实现热门话题标签tag显示控件

话题标签tag显示非常常见,如选择你的兴趣,选择关注的群,超话,话题等等。

学习记录,每天不停进步。

相关推荐
gxhlh3 小时前
局域网中 Windows 与 Mac 互相远程连接的最佳方案
windows·macos
宏基骑士3 小时前
mac 电脑上安装adb命令
macos·adb
胖虎15 小时前
实现 iOS 自定义高斯模糊文字效果的 UILabel(文末有Demo)
ios·高斯模糊文字·模糊文字
水银嘻嘻10 小时前
【Mac】Python相关知识经验
开发语言·python·macos
梦魇梦狸º1 天前
mac 配置 python 环境变量
chrome·python·macos
编程小猹1 天前
学习golang语言时遇到的难点语法
学习·golang·xcode
丁总学Java1 天前
macOS如何进入 Application Support 目录(cd: string not in pwd: Application)
macos
qdprobot1 天前
Mixly米思齐1.0 2.0 3.0 软件windows版本MAC苹果电脑系统安装使用常见问题与解决
windows·macos
麦克Mapp1 天前
不用安装双系统,如何在mac上玩windows游戏呢?
macos
符小易1 天前
Mac苹果电脑 怎么用word文档和Excel表格?
macos·word·excel