日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ios开发 自定义btn_iOS一步步实现一个高度自定义UIButton控件

發布時間:2025/3/21 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ios开发 自定义btn_iOS一步步实现一个高度自定义UIButton控件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

需求背景

日常開發中UIButton的圖片與標題默認的布局是固定的,是在水平方向左右排列。但是我們會經常需要更改image和title的位置來實現需求,這是個很常見的需求就不多說了。所以下面就來談談如何一步步的實現一個高度自定義的UIButton控件。

實現思路

默認情況下,在button有固定的寬高值的時候,image和title是以相對左右排列,整體居中于button來顯示的,如果沒有固定的寬高值,即大小自適應的情況下,整個UIButton將自動縮放到剛好可以容納image和title的大小。如圖所示:

自適應大小.png

了解UIButton的各個屬性

在準備自定義之前,我們需要了解UIButton的各個屬性都是怎么運用和實現的,因為要修改title和image的位置與這些屬性是密不可分的。

因為這些都是基本的開發知識,我就不再過多敘述,分別以圖片來展示效果:

UIControlContentVerticalAlignment

UIControlContentVerticalAlignment各種效果.png

UIControlContentHorizontalAlignment

UIControlContentHorizontalAlignment各種效果.png

通過上面兩張圖可以清楚地看到UIControlContentVerticalAlignment和UIControlContentHorizontalAlignment在不同值下的效果,灰色背景的就是一個button的實際大小,center就是系統默認的值,明顯的在兩種fill值下,圖片都出現了拉伸的情況,而且在水平fill下,圖片并沒有像垂直情況下水平鋪滿整個控件,image和title還重疊到了一起去。

UIEdgeInsets

UIButton的另一個重要的屬性就是這個了,稱之為偏移量,他分別有contentEdgeInsets,imageEdgeInsets,titleEdgeInsets三個相關屬性。

默認情況下:contentEdgeInsets的top、left、bottom、right都是相對于button本身,控制著image和title整體的偏移量;

imageEdgeInsets的top、left、bottom相對于button,right相對于title,控制著image的相對偏移量;

titleEdgeInsets的top、bottom、right相對于button,left相對于image,控制著title的相對偏移量;

我用一張圖來解釋一下:

偏移量.png

上圖的正負值就代表偏移方向

我們想要的效果

寫到這里,我們需要考慮一下我們的需求,我們并不是來分析button的實現原理,而是要實現一個自定義的button,自定義image和title的相對位置是最起碼的要求。相信看到這里大家也知道我們只需要修改imageEdgeInsets和titleEdgeInsets的值就可以隨意布局image和title的相對位置。比如左title右image,上image下title。

要實現這個需求有兩種方式:新建一個UIButton的分類UIButton + xx,在layoutSubviews里修改imageEdgeInsets和titleEdgeInsets的值。這種方式可以簡單實現我們的基本需求,但如果想要添加更多的自定義屬性還需要通過runtime來實現,好處就是擁有調用系統API的舒爽,直接UIButton調用,沒什么代碼侵入性。

封裝一個繼承自UIButton的CustomButton,可以自由添加自定義方法、屬性,在layoutSubviews里重置image和title的frame來實現不同的布局方式。

其實這兩種方式都可以實現自定義的效果,具體選用哪個就看你自己的需求了,我這里就第二種方式來實現一下。

上面所說到的contentEdgeInsets,imageEdgeInsets,titleEdgeInsets默認值都是zero,但是我們現在假設他們都有一個默認值x;

button簡易圖示.png

這里實現的思路就是通過self.bounds減去四周的偏移量先獲取整個content的實際size,再由contentSize減去image和title的對應偏移量來獲取image和title的實際size。總之就是先獲取image和title的實際大小,然后根據不同的布局重置image和title的x、y坐標和bound,從而得到對應的frame,就可以實現自由布局了。

上面所說的是button有固定寬高值的情況,如果button的寬高自適應,即調用sizeToFit方法時,我們需要在- (CGSize)sizeThatFits:(CGSize)size內針對不同情況重新計算出button的size,不然的話,系統會根據image和title的大小默認返回它們左右排列的size,此時的size是錯誤的,如圖:

沒做適配的結果.png

具體的布局分析思路就是這些了,因為代碼太多,就不在這里粘貼詳細代碼了,如果需要代碼的可以在文章底部找到demo的下載鏈接,demo里面也有詳細的注釋說明。

但是,到這里我們只是自定義了image和title的相對布局,我們的目的是自定義整個UIButton,所以系統默認的點擊效果,CALayer的所有默認動畫都需要移除掉,替換成我們自定義的layer效果。比如說系統button的默認高亮狀態下圖片顏色也會加深,這個其實很惡心,所以我們應該移除掉,就像圖下所示:

系統button高亮狀態.png

ok,現在我們來整理一下需要的常用屬性,分別為normal、highlighted、disabled這幾種狀態下的背景色,透明度變化,圖片的tintColor,邊框線的顏色,我們就針對這幾個點進行修改。

下面粘貼幾塊代碼段大概展示一下:

highlighted邏輯-?(void)setHighlighted:(BOOL)highlighted?{

[super?setHighlighted:highlighted];

if?(highlighted?&&?!self.originBorderColor)?{

//?手指按在按鈕上會不斷觸發setHighlighted:,所以這里做了保護,設置過一次就不用再設置了

self.originBorderColor?=?[UIColor?colorWithCGColor:self.layer.borderColor];

}

//?渲染背景色

if?(self.highlightedBackgroundColor?||?self.highlightedBorderColor)?{

[self?adjustsButtonHighlighted];

}

//?如果此時是disabled,則disabled的樣式優先

if?(!self.enabled)?{

return;

}

//?自定義highlighted樣式

if?(self.adjustsButtonWhenHighlighted)?{

if?(highlighted)?{

self.alpha?=?0.5f;

}?else?{

[UIView?animateWithDuration:0.25f?animations:^{

self.alpha?=?1;

}];

}

}

}

enabled邏輯-?(void)setEnabled:(BOOL)enabled?{

[super?setEnabled:enabled];

if?(!enabled?&&?self.adjustsButtonWhenDisabled)?{

self.alpha?=?0.5f;

}?else?{

[UIView?animateWithDuration:0.25f?animations:^{

self.alpha?=?1;

}];

}

}

移除系統layer,添加自定義layer-?(void)adjustsButtonHighlighted?{

if?(self.highlightedBackgroundColor)?{

if?(!self.highlightedBackgroundLayer)?{

self.highlightedBackgroundLayer?=?[CALayer?layer];

[self.highlightedBackgroundLayer?FS_removeDefaultAnimations];

[self.layer?insertSublayer:self.highlightedBackgroundLayer?atIndex:0];

}

self.highlightedBackgroundLayer.frame?=?self.bounds;

self.highlightedBackgroundLayer.cornerRadius?=?self.layer.cornerRadius;

self.highlightedBackgroundLayer.backgroundColor?=?self.highlighted???self.highlightedBackgroundColor.CGColor?:?[UIColor?colorWithRed:1?green:1?blue:1?alpha:0].CGColor;

}

if?(self.highlightedBorderColor)?{

self.layer.borderColor?=?self.highlighted???self.highlightedBorderColor.CGColor?:?self.originBorderColor.CGColor;

}

}

因為需要大量的自定義屬性來代替系統默認屬性,雖然我很想在這里解釋每個屬性的用處,但是太麻煩了,所以還是建議直接下載demo,配合代碼看文章,代碼有詳細的注釋

這里就直接展示一下demo的效果圖:

FSCustomButtonDemo.gif

以前項目用到的時候,我也是直接網上找的一個庫,不過那個庫包含內容太多,很多都沒用,所以我將其中的部分代碼抽離了出來直接在項目中運用,效果還可以很穩定,所以最近抽時間將代碼從項目中抽離封裝了一下,寫了一個demo上傳在github,需要的可以直接前往下載:

文章和demo中涉及到的知識點:

如果對你有所幫助,就點個贊吧作者:PURE藍胖子

鏈接:http://www.jianshu.com/p/4603e9bbba56

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的ios开发 自定义btn_iOS一步步实现一个高度自定义UIButton控件的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。