詳解iOS App開發(fā)中改變UIButton內部控件的基本方法
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?,F(xiàn)在如果我們想讓UIImage顯示在這個button的上面,讓UIButtonLabel顯示在這個button的下面。
我們可以完全自定義一個控件來實現(xiàn)上面所說的,也可以在UIButton的基礎上改變它的內部子控件。這里采用第二種方法。
1.首先,如果想改變子控件的位置,那么最先想到的可能是拿到這個button,然后通過訪問它的imageView和titleLabel屬性。
我們可以首先對這個button打印一下看看內部的結構:
NSLog(@"%@", self.button.subviews);
打印的結果是一個空數(shù)組!這是怎么回事呢?
實際上UIButton內部的子控件采用的是懶加載,也就是說如果沒有使用到相應的子控件,那么是不會加載的。
那么我們就重新給這兩個控件的frame賦值,這樣不僅用到了這兩個控件使其加載,也可以看看是否可以直接改變這兩個控件的frame以達到將這兩個控件重新排列的目的。
但是如果你這么做,你會發(fā)現(xiàn)實際顯示的這個button內部并沒有改變,說明直接改變UIButton內部控件的frame是無法達到重新排列的目的的。
接著將這個button內部的子控件打印出來:
NSLog(@"%@", self.button.subviews);
會發(fā)現(xiàn)subviews這個數(shù)組里現(xiàn)在是一個UIImageView + 一個UIButtonLabel,現(xiàn)在它們有了值(因為前面用到了這兩個控件,所以進行了懶加載)。
可是仔細觀察,會發(fā)現(xiàn)這兩個控件的frame明明是我們剛剛賦值的frame,但是顯示出來的為什么又不是按這個frame顯示的呢?
因為打印出來的frame只是我們剛剛設置的,而UIButton在顯示的時候會根據(jù)它的UIImageView和UIButtonLabel里面的內容重新計算大小,所以即使我們改變了子控件的frame,也無法真正更改子控件的位置和尺寸。
2.第二種思路是可以繼承UIButton,在原來的按鈕的基礎上進行改變。
比如我們創(chuàng)建一個UIButton的子類CYLButton,在CYLButton的實現(xiàn)文件中實現(xiàn)下面的方法:
- (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,但是當執(zhí)行到內部的layoutSubviews方法的時候會重新將它們的frame設置為image和title對應的大小。而現(xiàn)在我們直接在layoutSubviews中修改它們的frame,相當于覆蓋了之前將它們的frame設置為默認大小這一步驟,所以現(xiàn)在是可以成功的,并且因為在一個方法中,是可以共享變量的。
另外需要注意,如果繼承自UIButton(比如CYLButton),那么當有了數(shù)據(jù)模型,想在CYLButton的setter方法中給子控件賦值的時候,不能直接這樣:
self.imageView = ...
self.text = ...
因為self(CYLButton)是繼承自UIButton,所以無論是image還是title都是分狀態(tài)的,所以需要這樣:
[self setImage...];
[self setTitle...];
所以說能不能直接修改,取決于這個屬性分不分狀態(tài)。如果分狀態(tài),那么就不能直接修改。
- iOS開發(fā)中UIDatePicker控件的使用方法簡介
- 學習iOS開關按鈕UISwitch控件
- 詳解iOS開發(fā)中UIPickerView控件的使用方法
- iOS App開發(fā)中的UIPageControl分頁控件使用小結
- iOS應用開發(fā)中的文字選中操作控件UITextView用法講解
- iOS開發(fā)中UIImageView控件的常用操作整理
- 詳解iOS開發(fā)中UItableview控件的數(shù)據(jù)刷新功能的實現(xiàn)
- iOS應用開發(fā)中視圖控件UIWindow的基本使用教程
- iOS App中UIPickerView選擇欄控件的使用實例解析
- iOS中各種UI控件屬性設置示例代碼
相關文章
IOS開發(fā)代碼分享之設置UISearchBar的背景顏色
在項目開發(fā)中,我們經(jīng)常要用到UISearchBar,在網(wǎng)上看到了很多關于去除掉他背景色的方法,都已經(jīng)失效了,今天來分享一個正常使用的方法,希望能幫到大家2014-09-09iOS UITableView 與 UITableViewController實例詳解
這篇文章主要介紹了iOS UITableView 與 UITableViewController實例詳解的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-09-09IOS中(assign,retain,copy,weak,strong)的區(qū)別以及nonatomic的含義
這篇文章主要介紹了我們在聲明@property 屬性時,總是要在括號中寫上assign、retain、copy、weak、strong中的一個,他們的區(qū)別,需要的朋友可以參考下2017-03-03