2010-11-09 38 views
99

Trong trình tạo giao diện, giữ Lệnh + = sẽ đổi kích thước nút để phù hợp với văn bản của nó. Tôi đã tự hỏi nếu điều này đã có thể làm lập trình trước khi nút đã được thêm vào xem.iOS: UIButton đổi kích thước theo độ dài văn bản

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 
[button.titleLabel setFont:[UIFont fontWithName:@"Arial-BoldMT" size:12]]; 
[button addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside]; 
// I need to know the width needed to accomodate NSStringVariable 
[button setTitle:NSStringVariable forState:UIControlStateNormal]; 
// So that I can set the width property of the button before addSubview 
[button setFrame:CGRectMake(10, 0, width, fixedHeight)]; 
[subNavigation addSubview:button]; 
+1

** Lưu ý cho câu hỏi rất cũ này: ** ngày nay (2017), chỉ cần đặt ràng buộc là "lớn hơn hoặc bằng" và thực hiện tất cả. (Thông báo trả lời dưới đây bởi Tad.) – Fattie

Trả lời

12

Trong XCode 4.5 trở lên, điều này có thể bây giờ được thực hiện bằng cách sử dụng 'Tự động bố cục/Constraints'.

lợi thế chính là rằng:

  1. Bạn không cần phải programatically thiết lập khung ở tất cả!
  2. Nếu làm đúng, bạn không cần phải bận tâm về việc đặt lại khung cho các thay đổi định hướng.
  3. Ngoài ra, thay đổi thiết bị không cần làm phiền bạn (đọc, không cần mã riêng cho các kích thước màn hình khác nhau).

Một vài nhược điểm:

  1. Không tương thích ngược - chỉ hoạt động cho iOS 6 trở lên.
  2. Cần làm quen (nhưng sẽ tiết kiệm thời gian sau).

Coolest điều là chúng ta có được để tập trung vào tuyên bố một ý định như:

  • Tôi muốn hai nút này để có chiều rộng tương tự; hoặc
  • Tôi cần chế độ xem này được căn giữa theo chiều dọc và mở rộng đến mức tối đa 10 điểm từ cạnh của người giám sát; hoặc thậm chí,
  • Tôi muốn nút/nhãn này đổi kích thước theo nhãn đang hiển thị!

Here là hướng dẫn đơn giản để được giới thiệu về bố cục tự động.

Đối với số more details.

Mất chút thời gian lúc đầu, nhưng có vẻ như nó sẽ rất đáng để thử.

Chúc mừng!

+3

Tôi gần như đã bỏ lỡ câu trả lời này - nó thực sự cần nhiều phiếu bầu hơn. Với giải pháp này, người dùng có thể tránh nhúng các tên và kích cỡ phông chữ hoặc các cuộc gọi chỉ dành cho iOS 7. Tôi chỉ đơn giản là thiết lập các ràng buộc của phía tôi muốn UIButton của tôi để mở rộng trên và đó là nó. – Carl

+0

Hầu như là một giải pháp hoàn hảo, không may là nó không hoạt động nếu bạn sử dụng titleEdgeInsets:/ –

+57

Đây là câu trả lời kém - nó chi tiết giá trị của AutoLayout, thay vì cách AutoLayout có thể được áp dụng trong tình huống này để giải quyết vấn đề của người hỏi. – mattsven

118

Trong UIKit, có bổ sung vào lớp NSString để có được từ một NSString cho đối tượng kích thước nó sẽ mất khi kết xuất trong một phông chữ nhất định.

Tài liệu here.

Nói tóm lại, nếu bạn đi:

CGSize stringsize = [myString sizeWithFont:[UIFont systemFontOfSize:14]]; 
//or whatever font you're using 
[button setFrame:CGRectMake(10,0,stringsize.width, stringsize.height)]; 

... bạn sẽ đã thiết lập khung của nút với chiều cao và chiều rộng của chuỗi bạn đang render.

Có thể bạn sẽ muốn thử nghiệm với một số vùng đệm xung quanh CGSize đó, nhưng bạn sẽ bắt đầu ở đúng nơi.

+4

Hình như đệm mặc định của iOS là 12px, 8px. –

+17

sizeWithFont không được chấp nhận trong iOS 7.0. Sử dụng sizeWithAttributes: thay vì –

+6

Tôi khuyên bạn không nên chơi với khung hình nữa, nhưng CHỈ với các ràng buộc thay thế. –

84

Cách để làm điều này trong mã là:

[button sizeToFit]; 

Nếu bạn đang subclassing và muốn thêm các quy tắc thêm bạn có thể ghi đè lên:

- (CGSize)sizeThatFits:(CGSize)size; 
+3

sizeToFit hoạt động hoàn hảo trên các nút điều khiển chuẩn như UIButton hoặc UILabel. Nếu bạn đang làm nó trên một UIView tùy chỉnh, bạn sẽ cần phải thực hiện '- (CGSize) sizeThatFits: (CGSize) size'. –

+3

Nó chỉ hoạt động nếu bạn đặt nó sau khi đặt văn bản, nếu không không đủ thông tin về mức độ lớn: '[nút setTitle: @" Văn bản của bạn ở đây "forState: UIControlStateNormal];' '[button sizeToFit ]; ' Ngoài ra nếu bạn cập nhật văn bản sau, đừng quên gọi lại điều đó. –

+0

Đảm bảo rằng bạn chỉ đặt văn bản theo cách đó: [myButton setTitle: @ "tiêu đề của tôi" forState: UIControlStateNormal]; Đối với tôi nó không hoạt động cho đến khi tôi lặp lại câu nói đó. –

31

Nếu nút của bạn đã được thực hiện với giao diện Builder, và bạn đang thay đổi tiêu đề bằng mã, bạn có thể làm điều này:

[self.button setTitle:@"Button Title" forState:UIControlStateNormal]; 
[self.button sizeToFit]; 
+0

Và bạn có thể làm điều đó ngay cả khi nút của bạn được tạo bằng mã. – Markus

2

Tôi có một số nhu cầu bổ sung liên quan bài đăng này sizeToFit không giải quyết được. Tôi cần giữ nút ở giữa vị trí ban đầu của nó, bất kể văn bản. Tôi cũng không bao giờ muốn nút lớn hơn kích thước ban đầu của nó.

Vì vậy, tôi bố trí các nút cho kích thước tối đa, tiết kiệm kích thước mà trong điều khiển và sử dụng các phương pháp sau đây để kích thước các nút khi những thay đổi văn bản:

+ (void) sizeButtonToText:(UIButton *)button availableSize:(CGSize)availableSize padding:(UIEdgeInsets)padding {  

    CGRect boundsForText = button.frame; 

    // Measures string 
    CGSize stringSize = [button.titleLabel.text sizeWithFont:button.titleLabel.font]; 
    stringSize.width = MIN(stringSize.width + padding.left + padding.right, availableSize.width); 

    // Center's location of button 
    boundsForText.origin.x += (boundsForText.size.width - stringSize.width)/2; 
    boundsForText.size.width = stringSize.width; 
    [button setFrame:boundsForText]; 
} 
13

Nếu bạn muốn thay đổi kích thước văn bản như trái ngược với các nút, bạn có thể sử dụng ...

button.titleLabel.adjustsFontSizeToFitWidth = YES; 
button.titleLabel.minimumScaleFactor = .5; 
// The .5 value means that I will let it go down to half the original font size 
// before the texts gets truncated 

// note, if using anything pre ios6, you would use I think 
button.titleLabel.minimumFontSize = 8; 
+3

* adjustsFontSizeToFitWidth –

11

Swift:

Điều quan trọng ở đây là khi sẽ gọi .sizeToFit(), phải sau khi đặt văn bản để hiển thị để có thể đọc kích thước cần thiết, nếu sau này bạn cập nhật văn bản, sau đó gọi lại.

var button = UIButton() 
button.setTitle("Length of this text determines size", forState: UIControlState.Normal) 
button.sizeToFit() 
self.view.addSubview(button) 
3

Đơn giản chỉ cần:

  1. Tạo UIView như wrapper với bố cục tự động để xem xung quanh.
  2. Đặt UILabel bên trong trình bao bọc đó. Thêm các ràng buộc sẽ gắn nhãn tyour vào các cạnh của trình bao bọc.
  3. Đặt UIButton bên trong trình bao bọc của bạn, sau đó thêm các ràng buộc giống như bạn đã thực hiện cho UILabel.
  4. Tận hưởng nút được tự động hóa của bạn cùng với văn bản.
1

sizeToFit không hoạt động chính xác. thay vì:

myButton.size = myButton..sizeThatFits(CGSize.zero) 

bạn cũng có thể thêm contentInset nút:

myButton.contentEdgeInsets = UIEdgeInsetsMake(8, 8, 4, 8)

+0

Từ tài liệu của Apple liên quan đến sizeToFit: // calls sizeThatFits: với giới hạn lượt xem hiện tại và thay đổi kích thước giới hạn. Vì vậy, nó hoạt động chính xác bạn chỉ cần thiết lập nó sau đó bạn thiết lập văn bản. – Markus

+0

contentEdgeInsets phù hợp với tôi! – ElectroBuddha

8

Để thực hiện điều này bằng autolayout, hãy thử đặt chiều rộng chế biến:

Width Constraint

Bạn cũng có thể cần điều chỉnh Content Hugging PriorityContent Compression Resistance Priority t của bạn o có được kết quả bạn cần.

Các vấn đề liên quan