UIButton's title and image custom layout, uibuttontitle
When you need to implement a button for custom Layout pictures and titles, you do not know how many teenagers directly layout UIButton or customize a UIView, then, use blank UIButton, UILabel, and UIImageVew as subViews.
The two are actually the same, because UIButton's internal subViews already have a UILabel and UIImageView.
Without talking about advantages and disadvantages, we only record the process of directly deploying UIButton.
Because UIButton already has a UILabel title and an ImageView, you can directly layout it. However, pay attention to the following record issues.
First, you can directly set the title (using the setTitle or setAttributedTitle method) and image (using the setImage method) for a UIButton instance button, and you will find that the image and the title are closely aligned and centered.
Then, modify the titleLabel of the button and the frame of the imageView to find that it has no effect.
Finally, if you try setTitleEdgeInsets and setImageEdgeInsets, you will find that they do not work or the layout is abnormal.
The problem is:
1. When obtaining the frame of titleLabel, the size is always (0, 0)
2. The frame modification time of titleLabel is incorrect.
It is appropriate to place the above modification operations in the layoutSubviews method.
You can use the swizzle method to create a UIButton subclass or create a category.
Even at this time point, using setTitleEdgeInsets may still cause incomplete text display. We recommend that you directly modify the frame of titleLabel.
I used the solution to create a category. Defines a method to exchange with layoutSubViews in the + load method.
- (void)base_layoutSubviews{ [self base_layoutSubviews]; if (self.resetTitleAndImageLayoutBlock) { self.resetTitleAndImageLayoutBlock(); }}
The block Variable customized in the code will delay the reset layout code to be called here.
The following code is the main method used to customize the layout of images and titles in UIButton classification. Currently, only four types of image positions are customized:
-(Void) resetButtonTitleAndImageLayoutWithMidInset :( CGFloat) midInset imageLocation :( ButtonImageLocation) imageLocation {CGSize titleSize = [self. titleLabel. attributedText boundingRectWithSize: CGSizeMake (MAXFLOAT, MAXFLOAT) options: NSStringDrawingUsesLineFragmentOrigin context: nil]. size; CGSize imageSize = self. imageView. size; _ weak typeof (self) weakSelf = self; // because UIButton resets the frame of titleLabel during layoutSubviews, it is necessary to call block self by delay. resetTitleAndImageLayoutBlock = ^ {switch (imageLocation) {case ButtonImageLocationUp: {CGFloat imageOriginX = (weakSelf. width-imageSize. width)/2.0; CGFloat imageOriginY = (weakSelf. height-titleSize. height-midInset-imageSize. height)/2.0; weakSelf. imageEdgeInsets = UIEdgeInsetsMake (imageOriginY, imageOriginX, weakSelf. height-imageOriginY-imageSize. height, imageorig)); CGFloat titleOriginX = (weakSelf. width-titleSize. width)/2.0; CGFloat titleOriginY = imageOriginY + imageSize. height + midInset; weakSelf. titleEdgeInsets = UIEdgeInsetsMake (titleOriginY, titleOriginX INX, weakSelf. height-titleOriginY-titleSize. height, titleorigorig); break;} case ButtonImageLocationLeft: {CGFloat imageOriginX = (weakSelf. width-imageSize. width-midInset-titleSize. width)/2.0; CGFloat imageOriginY = (weakSelf. height-imageSize. height)/2.0; weakSelf. imageEdgeInsets = UIEdgeInsetsMake (imageOriginY, imageOriginX INX, imageOriginY, weakSelf. width-imageOriginX-imageSize. width); CGFloat titleorig.pdf = imageOriginX + imageSize. width + midInset; // when horizontal, the frame of the label can be in a large range. // CGFloat titleOriginY = (weakSelf. height-titleSize. height)/2.0; // weakSelf. titleLabel. frame = CGRectMake (titleOriginX INX, titleOriginY, titleSize. width, titleSize. height); weakSelf. titleLabel. frame = CGRectMake (titleorigtasks, 0, weakSelf. width-titleOriginX, weakSelf. height); [weakSelf. titleLabel setTextAlignment: NSTextAlignmentLeft]; break;} case ButtonImageLocationDown: {CGFloat titleOriginX =( weakSelf. width-titleSize. width)/2.0; CGFloat titleOriginY = (weakSelf. height-titleSize. height-midInset-imageSize. height)/2.0; weakSelf. titleEdgeInsets = UIEdgeInsetsMake (titleOriginY, titleOriginX INX, weakSelf. height-titleOriginY-titleSize. height, titleorigorig); CGFloat imageOriginX = (weakSelf. width-imageSize. width)/2.0; CGFloat imageOriginY = titleOriginY + titleSize. height + midInset; weakSelf. imageEdgeInsets = UIEdgeInsetsMake (imageOriginY, imageOriginX, weakSelf. height-imageOriginY-imageSize. height, imageorig)); break;} case ButtonImageLocationRight: {CGFloat titleOriginX = (weakSelf. width-imageSize. width-midInset-titleSize. width)/2.0; // when horizontal, the frame of the label can be in a large range. // CGFloat titleOriginY = (weakSelf. height-titleSize. height)/2.0; // weakSelf. titleLabel. frame = CGRectMake (titleOriginX INX, titleOriginY, titleSize. width, titleSize. height); weakSelf. titleLabel. frame = CGRectMake (0, 0, titleOriginX + titleSize. width, weakSelf. height); [weakSelf. titleLabel setTextAlignment: NSTextAlignmentRight]; CGFloat imageOriginX INX = titleorig+ + titleSize. width + midInset; CGFloat imageOriginY = (weakSelf. height-imageSize. height)/2.0; weakSelf. imageEdgeInsets = UIEdgeInsetsMake (imageOriginY, imageOriginX INX, imageOriginY, weakSelf. width-imageOriginX-imageSize. width); break ;}}};}
For the complete code, see UIButton classification in the Base project.
Base project Updated: https://github.com/ALongWay/base.git