自定义控件之调整按钮中子控件(图片和文字)的位置
其实还有一种是在storyBoard中实现的,只需要设置对应空间的左右间距:
这里实现前面两种自定义的方式
一:imageRectForContentRect/titleRectForContentRect
自定义一个按钮控件在系统自带的位置设置方法中实现对应子控件位置调整
/** * 设置内部图标的frame */ - (CGRect)imageRectForContentRect:(CGRect)contentRect { CGFloat imageY = ; CGFloat imageW = self.height; CGFloat imageH = imageW; CGFloat imageX = self.width - imageW; return CGRectMake(imageX, imageY, imageW, imageH); } /** * 设置内部文字的frame */ - (CGRect)titleRectForContentRect:(CGRect)contentRect { CGFloat titleY = ; CGFloat titleX = ; CGFloat titleH = self.height; CGFloat titleW = self.width - self.height; return CGRectMake(titleX, titleY, titleW, titleH); }
然后做进步一的优化:
- (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // 内部图标居中 self.imageView.contentMode = UIViewContentModeCenter; // 文字对齐 self.titleLabel.textAlignment = NSTextAlignmentRight; // 文字颜色 [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; // 字体 self.titleLabel.font = HMNavigationTitleFont; // 高亮的时候不需要调整内部的图片为灰色 self.adjustsImageWhenHighlighted = NO; } return self; } - (void)setTitle:(NSString *)title forState:(UIControlState)state { [super setTitle:title forState:state]; // 1.计算文字的尺寸 CGSize titleSize = [title sizeWithFont:self.titleLabel.font]; // 2.计算按钮的宽度 self.width = titleSize.width + self.height + ; }
二:类似签名的自定义View在layoutSubViews里面实现子控件位置的调整:
创建一个继承自UIButton得子类,实现响应的自定义子控件的方法
- (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { //设置文字颜色 [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; //设置文字大小 self.titleLabel.font = [UIFont boldSystemFontOfSize:]; //设置按钮的图片(普通和选中) [self setImage:[UIImage imageNamed:@"navigationbar_arrow_down"] forState:UIControlStateNormal]; [self setImage:[UIImage imageNamed:@"navigationbar_arrow_up"] forState:UIControlStateSelected]; } return self; } - (void)layoutSubviews { [super layoutSubviews]; // 如果仅仅是调整按钮内部titleLabel和imageView的位置,那么在layoutSubviews中单独设置位置即可 // 1.计算titleLabel的frame self.titleLabel.x = self.imageView.x - ; // 2.计算imageView的frame self.imageView.x = CGRectGetMaxX(self.titleLabel.frame); } - (void)setTitle:(NSString *)title forState:(UIControlState)state { [super setTitle:title forState:state]; // 只要修改了文字,就让按钮重新计算自己的尺寸 [self sizeToFit]; } - (void)setImage:(UIImage *)image forState:(UIControlState)state { [super setImage:image forState:state]; // 只要修改了图片,就让按钮重新计算自己的尺寸 [self sizeToFit]; }
最后来看看Swift怎么去实现:
class ShopButton: UIButton { var shop: Shop? { didSet { print(shop) // 重写set方法 /* // 错误写法 self.imageView?.image = UIImage(named: shop!.icon) self.titleLabel?.text = shop!.name */ self.setTitle(shop!.name, forState: UIControlState.Normal) self.setImage(UIImage(named: shop!.icon), forState: UIControlState.Normal) } } class func shopView(shop: Shop) -> ShopButton{ let btn:ShopButton = ShopButton() btn.shop = shop return btn } /* override func titleRectForContentRect(contentRect: CGRect) -> CGRect { return CGRectMake(0, contentRect.size.width, contentRect.size.width, contentRect.size.height - contentRect.size.width) } override func imageRectForContentRect(contentRect: CGRect) -> CGRect { return CGRectMake(0, 0, contentRect.size.width, contentRect.size.width) } */ override func layoutSubviews() { super.layoutSubviews() print(self.frame) let width: CGFloat = self.frame.size.width let height: CGFloat = self.frame.size.height self.imageView?.frame = CGRectMake(, , width, width) self.titleLabel?.frame = CGRectMake(, width, width, height - width) } }
其实思路非常简单,就是设置对应控件的frame就可以,当然如果真的不想写那么就直接使用吧,使用方法有两种直接创建设置对应的子控件需要的值或者在XIB或StoryBoard中给对应的UIButton控件设置为我们自定义的类就可以。