UIButton外部默許有個UIImageView、UILabel控件,可以分離用上面屬性拜訪:
@property(nonatomic,readonly,retain) UIImageView *imageView;
@property(nonatomic,readonly,retain) UILabel *titleLabel;
UIButton之所以能顯示文字,完整是由於它外部的titleLabel也,也就是說,UIButton的setTitle:forState:辦法設置的字符串就是顯示到了titleLabel上
UIButton的setImage:forState:辦法設置的圖片顯示到了外部的imageView上。
留意:
1.設置按鈕的文字或文字色彩,必需用上面的辦法
- (void)setTitle:(NSString *)title forState:(UIControlState)state;
- (void)setTitleColor:(UIColor *)color forState:(UIControlState)state;
warnning:不克不及直接拿到titleLabel設置文字和文字色彩,好比上面的做法是毛病的:
button.titleLabel.text = @"12323";
button.titleLabel.textColor = [UIColor redColor];
2.設置按鈕外部的小圖片,必需用上面的辦法
- (void)setImage:(UIImage *)image forState:(UIControlState)state;
warnning:不克不及直接拿到imageView設置圖片,好比上面的做法是毛病的:
button.imageView.image = [UIImage imageNamed:@"abc.png"];
好了,回想完以後,我們上面來進入本文的主題~
轉變UIButton外部控件
當給UIButton設置title和image後,就相當於UIButton是由一個UIButtonLabel + 一個UIImageView構成。然則它們默許的格局是固定的,即左面是一個UIImage,左面是一個UIButtonLabel。如今假如我們想讓UIImage顯示在這個button的下面,讓UIButtonLabel顯示在這個button的上面。
我們可以完整自界說一個控件來完成下面所說的,也能夠在UIButton的基本上轉變它的外部子控件。這裡采取第二種辦法。
1.起首,假如想轉變子控件的地位,那末最早想到的能夠是拿到這個button,然後經由過程拜訪它的imageView和titleLabel屬性。
我們可以起首對這個button打印一下看看外部的構造:
NSLog(@"%@", self.button.subviews);
打印的成果是一個空數組!這是怎樣回事呢?
現實上UIButton外部的子控件采取的是懶加載,也就是說假如沒有應用到響應的子控件,那末是不會加載的。
那末我們就從新給這兩個控件的frame賦值,如許不只用到了這兩個控件使其加載,也能夠看看能否可以直接轉變這兩個控件的frame以到達將這兩個控件從新分列的目標。
然則假如你這麼做,你會發明現實顯示的這個button外部並沒有轉變,解釋直接轉變UIButton外部控件的frame是沒法到達從新分列的目標的。
接著將這個button外部的子控件打印出來:
NSLog(@"%@", self.button.subviews);
會發明subviews這個數組裡如今是一個UIImageView + 一個UIButtonLabel,如今它們有了值(由於後面用到了這兩個控件,所以停止了懶加載)。
可是細心不雅察,會發明這兩個控件的frame明明是我們方才賦值的frame,然則顯示出來的為何又不是按這個frame顯示的呢?
由於打印出來的frame只是我們方才設置的,而UIButton在顯示的時刻會依據它的UIImageView和UIButtonLabel外面的內容從新盤算年夜小,所以即便我們轉變了子控件的frame,也沒法真正更改子控件的地位和尺寸。
2.第二種思緒是可以繼續UIButton,在本來的按鈕的基本長進行轉變。
好比我們創立一個UIButton的子類CYLButton,在CYLButton的完成文件中完成上面的辦法:
- (CGRect)titleRectForContentRect: (CGRect)contentRect // 掌握label顯示在哪和年夜小
{
return CGRectMake(0, contentRect.size.width, contentRect.size.width, contentRect.size.height - contentRect.size.width);
}
- (CGRect)imageRectForContentRect: (CGRect)contentRect // 掌握image顯示在哪和年夜小
{
return CGRectMake(0, 0, contentRect.size.width, contentRect.size.width);
}
// contentRect普通來代表UIButton的bounds.size
// 我們也能夠在initWithFrame:辦法中設置UIButton的外部控件的屬性
- (instancetype)initWithFrame: (CGRect)frame
{
if (self = [super initWithFrame: frame]) {
self.titleLabel.backgroundColor = [UIColor blueColor];
self.titleLabel.textAlignment = NSTextAlignmentCenter;
self.imageView.backgroundColor = [UIColor yellowColor];
}
return self;
}
可以看到這類辦法可以知足我們的請求。然則也有弊病,假如我們在個中一個辦法中設置的某一些想在另外一個辦法中也用到,那末就不是很便利。
3.更好的辦法是重寫layoutSubviews辦法,由於這個辦法可以很便利地調劑子控件。
- (void)layoutSubviews
{
[super layoutSubviews];
CGFloat imageW = self.bounds.size.width;
CGFloat imageH = imageW;
self.imageView.frame = CGRectMake(0, 0, imageW, imageH);
CGFloat titleY = imageH;
CGFloat titleW = imageW;
CGFloat titleH = self.bounds.size.height - titleY;
self.titleLabel.frame = CGRectMake(0, titleY, titleW, titleH);
}
如許做能夠會很奇異,由於適才在這個類的裡面我們也轉變的是imageView和titleLabel的frame,可是毫無感化,而在layoutSubviews辦法裡異樣修正,為何會起感化了呢?
由於適才我們在裡面修正子控件的frame,然則當履行到外部的layoutSubviews辦法的時刻會從新將它們的frame設置為image和title對應的年夜小。而如今我們直接在layoutSubviews中修正它們的frame,相當於籠罩了之前將它們的frame設置為默許年夜小這一步調,所以如今是可以勝利的,而且由於在一個辦法中,是可以同享變量的。
別的須要留意,假如繼續自UIButton(好比CYLButton),那末當有了數據模子,想在CYLButton的setter辦法中給子控件賦值的時刻,不克不及直接如許:
self.imageView = ...
self.text = ...
由於self(CYLButton)是繼續自UIButton,所以不管是image照樣title都是分狀況的,所以須要如許:
[self setImage...];
[self setTitle...];
所以說能不克不及直接修正,取決於這個屬性分不分狀況。假如分狀況,那末就不克不及直接修正。
【詳解iOS App開辟中轉變UIButton外部控件的根本辦法】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!