[英]IOS UIButton (DLRadioButton) height doesn't depend on title label text size
[英]IOS: Adjust UIButton height depend on title text using Autolayout?
我有一個UIButton
,它可以在運行時更改標題。 因此,我想通過使用AutoLayout
根據標題文本增加UIButton
高度以顯示全文。
我可以通過將height constraint
設置為“大於或等於”來增加UILabel
高度,但它不適用於UIButton
。
我使用過[myButton sizeToFit]
但它只增加了UIButon
寬度(不增加高度)。
我當前的UIButton
屬性現在是
- 約束高度:30 - 前導:15 - 尾隨:15 - 頂部:5 - 字體大小:12
更新
我為UIButton
約束高度創建了一個 IBOutlet,用於更改@NSNood
所說的高度。
然后我需要在標題文本中使用\\n
來分割線。
但我不知道我應該把\\n
放在哪里?
這是我想要的縱向Button
如何確定放置\\n
?
請指導我如何使用AutoLayout
實現它。 任何幫助,將不勝感激。
抱歉,我最近沒有關注該帖子,因此我想出了一個真正遲到的解決方案。 如果將來有人可能會發現它有用,我仍然將答案寫為參考。
首先讓我們展示按鈕的故事板配置。 如下圖所示:
圖片顯示我只為按鈕添加了左、上和右約束,沒有其他任何內容。 這允許按鈕的高度有一些intrinsicContentSize
,但它的寬度仍然由它的左右約束決定。
下一階段是編寫一些包含按鈕的 ViewController 類。 在我的 VC 中,我按名稱button
為按鈕創建了一個插座:
@property(nonatomic,weak) IBOutlet UIButton* button;
並將其附加到故事板按鈕上。 現在我重寫了兩個方法,即viewDidLoad
和viewWillLayoutSubviews
如下所示:
-(void)viewDidLoad {
[super viewDidLoad];
self.button.titleLabel.numberOfLines = 0;
self.button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
}
-(void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
[self.button setTitle:@"Chapter One\n "
"A Stop on the Salt Route\n "
"1000 B.C.\n "
"As they rounded a bend in the path that ran beside the river, Lara recognized the silhouette of a fig tree atop a nearby hill. The weather was hot and the days were long. The fig tree was in full leaf, but not yet bearing fruit." forState:UIControlStateNormal];
}
viewDidLoad
方法確保titleLabel
(保存按鈕文本的標簽)是多行的,如果遇到一些大文本,它會通過包裝文字來包裝文本。viewWillLayoutSubviews
方法確保在主視圖的邊界發生變化時發生按鈕布局過程,例如由於界面方向的變化。 最后也是最有效的部分是手動處理按鈕的布局過程。 為此,我們需要UIButton
。 我編寫了一個繼承自UIButton
名為MyButton
的子類,您可以使用任何您喜歡的名稱。 將此設置為 Identity Inspector 中按鈕的自定義類。
子類覆蓋了兩個方法,即intrinsicContentSize
和layoutSubviews
。 類主體如下所示:
#import "MyButton.h"
@implementation MyButton
-(CGSize)intrinsicContentSize {
return [self.titleLabel sizeThatFits:CGSizeMake(self.titleLabel.preferredMaxLayoutWidth, CGFLOAT_MAX)];;
}
-(void)layoutSubviews {
self.titleLabel.preferredMaxLayoutWidth = self.frame.size.width;
[super layoutSubviews];
}
@end
UIButon
子類通過覆蓋layoutSubviews
方法獲取布局過程的所有權。 這里的基本思想是確定按鈕寬度,一旦它已經布局。 然后將寬度設置為它的子titleLabel
(保存按鈕文本的標簽)的preferredMaxLayoutWidth
(布局引擎的最大寬度,多行標簽應該占據)。 最后,根據titleLabel
的大小為按鈕返回一個intrinsicContentSize
大小,以便按鈕完全包裹它的titleLabel
。
layoutSubviews
。 在它的第一個步驟中,按鈕的呈現寬度被設定為preferredMaxLayoutWidth
按鈕的的titleLabel
。[super layoutSubviews]
重新調用布局引擎,以便按鈕的intrinsicContentSize
根據其titleLabel
的preferredMaxLayoutWidth
重新確定,此時該按鈕設置為按鈕呈現寬度。intrinsicContentSize
方法中,我們返回完全包裹它的titleLabel
並設置了preferredMaxLayoutWidth
的按鈕的最小擬合大小。 我們在按鈕的titleLabel
上使用sizeThatFits
fits 方法,這只是因為titleLabel
不遵循任何基於約束的布局。結果應該與您可能需要的類似。
請隨時讓我知道任何其他澄清/疑慮。
謝謝。
Swift 中的 Ayan Sengupta 解決方案,支持 contentEdgeInsets(感謝 Claus Jørgensen):
(如果需要,您還可以進一步自定義代碼以將titleEdgeInsets
考慮在內)
子類化您的 UIButton 以獲取布局過程的所有權:
/// https://stackoverflow.com/a/50575588/1033581 class AutoLayoutButton: UIButton { override var intrinsicContentSize: CGSize { var size = titleLabel!.sizeThatFits(CGSize(width: titleLabel!.preferredMaxLayoutWidth - contentEdgeInsets.left - contentEdgeInsets.right, height: .greatestFiniteMagnitude)) size.height += contentEdgeInsets.left + contentEdgeInsets.right return size } override func layoutSubviews() { titleLabel?.preferredMaxLayoutWidth = frame.size.width super.layoutSubviews() } }
在你的故事板中使用這個類,並為領先、尾隨、頂部、底部設置約束。 但不要設置任何高度約束。
另一種沒有子類化的替代方法是添加一個包裝視圖,如Bartłomiej Semańczyk 的回答和Timur Bernikowich 評論所建議的。
有一種方法我一直用:
完畢。 :)
PS1。 這種方式可用於滾動視圖中的按鈕和引用標簽。
PS2。 在某些情況下,我們無法獲得 ref-label 的正確高度,因為它無法在 scrollview 中獲得正確的 frame.width,尤其是當我們使用拖尾約束時。 我們可以考慮在 sizeTofit 之前為 ref-label 定義一個固定寬度,並獲得目標按鈕使用的正確高度。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.