UIButton với hai dòng văn bản trong tiêu đề (numberOfLines = 2)


86

Tôi đang cố tạo một UIButtoncó hai dòng văn bản trong titleLabel của nó. Đây là mã tôi đang sử dụng:

    UIButton *titleButton = [[UIButton alloc] initWithFrame:CGRectMake(15, 10, frame.size.width-100, 100)];
    titleButton.titleLabel.font = [UIFont boldSystemFontOfSize:24.0];
    [titleButton setTitle:@"This text is very long and should get truncated at the end of the second line" forState:UIControlStateNormal];
    titleButton.titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
    titleButton.titleLabel.numberOfLines = 2;
    [self addSubview:titleButton];

Khi tôi thử điều này, văn bản chỉ xuất hiện trên một dòng. Có vẻ như cách duy nhất để đạt được nhiều hơn một dòng văn bản UIButton.titleLabellà thiết lập numberOfLines=0và sử dụng UILineBreakModeWordWrap. Nhưng điều này không đảm bảo văn bản có chính xác hai dòng.

UILabelTuy nhiên, sử dụng đồng bằng vẫn hoạt động:

    UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(15, 10, frame.size.width-100, 100)];
    titleLabel.font = [UIFont boldSystemFontOfSize:24.0];
    titleLabel.text = @"This text is very long and should get truncated at the end of the second line";
    titleLabel.numberOfLines = 2;
    titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
    [self addSubview:titleLabel];

Có ai biết làm thế nào để làm cho UIButtoncông việc với hai dòng? Có phải giải pháp duy nhất để tạo một vùng riêng biệt UILabelđể giữ văn bản và thêm nó làm chế độ xem phụ của nút?


1
Bạn đã thấy cái này chưa ? - stackoverflow.com/questions/604632/…
Viraj

Viraj, vâng, nếu bạn đặt numberOfLines=0và sử dụng UILineBreakModeWordWrap, bạn có thể nhận được nhiều dòng. Vấn đề với điều đó là nó có thể cho nhiều hơn hai dòng nếu văn bản quá dài. Tôi muốn có chính xác hai lone với dấu chấm hết ở cuối dòng thứ hai (nếu văn bản quá dài).
marketer

Ồ, vậy thì tôi đoán việc thêm lượt xem phụ có thể là cách duy nhất.
Viraj

Câu trả lời:


87

Cập nhật câu trả lời cho các phiên bản iOS mới hơn

Vì đây là câu trả lời được chấp nhận nên đã thêm câu trả lời của @ Sean tại đây:

Đặt các thuộc tính này trên titleLabel của nút của bạn.

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.numberOfLines = 2; // if you want unlimited number of lines put 0

Swift 3 và 4:

button.titleLabel?.lineBreakMode = .byWordWrapping
button.titleLabel?.numberOfLines = 2 // if you want unlimited number of lines put 0

Câu trả lời ban đầu cho phiên bản iOS cũ hơn

Nếu bạn muốn có 2 dòng văn bản ở trên cùng, UIButtonbạn nên thêm một dòng văn bản ở trên cùng UIlabelđể thực hiện chính xác điều đó.

UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(15, 10, frame.size.width-100, 100)];
titleLabel.font = [UIFont boldSystemFontOfSize:24.0];
titleLabel.text = @"This text is very long and should get truncated at the end of the second line";
titleLabel.numberOfLines = 2;
titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
[myButton addSubview:titleLabel]; //add label to button instead.

Đã cập nhật cho giải pháp trình tạo giao diện

Đã thêm câu trả lời của @Borut Tomazin để có câu trả lời đầy đủ hơn. Cập nhật lại phần này vì câu trả lời của @Borut Tomazin đã được cải thiện.

Bạn có thể làm điều này dễ dàng hơn nhiều, không cần mã. Trong Bộ tạo giao diện đặt Line Breaktrên UIButton thành Word Wrap. Hơn bạn có thể chèn nhiều dòng tiêu đề. Chỉ cần nhấn Option + Returncác phím để tạo dòng mới. Bạn cũng sẽ cần thêm điều này vào Thuộc tính thời gian chạy do người dùng xác định trong trình tạo giao diện:

titleLabel.textAlignment Number [1]

5
UILineBreakModeđang bị phản đối, sử dụng NSLineBreakModethay vì nó
Guillaume

2
Điều này là không cần thiết đối với các phiên bản iOS gần đây. Xem câu trả lời của @ sean.
cbowns

146

Bạn không cần thêm UILabel vào UIButton. Đó chỉ là đối tượng phụ và công việc.

Đặt các thuộc tính này trên titleLabel của nút của bạn.

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.numberOfLines = 2;//if you want unlimited number of lines put 0

Nhanh:

button.titleLabel!.lineBreakMode = NSLineBreakMode.ByWordWrapping
button.titleLabel!.numberOfLines = 2//if you want unlimited number of lines put 0

6
Đây là năm 2013 và cho đến hôm nay đây là giải pháp hiện đại.
Klaas

@Blip bạn không thể tiếc và cần phải làm điều đó trong mã. Có thể đáng để gửi báo cáo lỗi với Apple để yêu cầu chức năng này.
bpapa

@bpapa Yep Tôi đồng ý, bảng phân cảnh nên linh hoạt hơn.
Blip

6
Điều này phù hợp với tôi, tuy nhiên nó phá vỡ hành vi mặc định của nút intrinsicContentSize, vẫn trả về chiều cao chỉ tương ứng với một dòng văn bản. Tôi đã sửa nó bằng cách ghi đè nút intrinsicContentSizenơi tôi đặt chiều cao [self.titleLabel sizeThatFits(CGSizeMake(self.titleLabel.frame.size.width, CGFLOAT_MAX)].height.
Elise

@WillVonUllrich vì bạn chỉ có thể thay đổi câu trả lời được chấp nhận khi nó được chỉnh sửa. Tôi đã thêm những câu trả lời này vào câu trả lời được chấp nhận để nó sẽ giúp những người không nhìn xa hơn câu trả lời được chấp nhận.
Totumus Maximus

88

Bạn có thể làm điều này dễ dàng hơn nhiều, không cần mã. Trong Bộ tạo giao diện đặt Line Breaktrên UIButton thành Word Wrap. Hơn bạn có thể chèn nhiều dòng tiêu đề. Chỉ cần nhấn Option + Returncác phím để tạo dòng mới. Bạn cũng sẽ cần thêm điều này vào Thuộc tính thời gian chạy do người dùng xác định trong trình tạo giao diện:

titleLabel.textAlignment Number [1]

Nó đơn giản mà. Hy vọng nó giúp...


1
Giải pháp này tốt hơn (ít đối tượng, mã hơn) so với giải pháp hiện đang được chấp nhận, cho các trường hợp đơn giản.
Jonathan Zhan

1
Bạn đặt các thuộc tính giống hệt như bạn làm theo chương trình nên đối số "ít đối tượng" của bạn không hợp lệ. Mã có thể ít hơn. Nhưng nó dễ đọc hơn. Hãy lựa chọn của bạn;)
Totumus Maximus

Ồ, tôi nghĩ tôi không rõ lắm. Cảm ơn vì đã cố gắng làm rõ. Không quan tâm nhiều đến thực tế là nó được thực hiện trong IB vs Code. Nhiều việc phải làm với thực tế là bạn không cần thêm nhãn bổ sung với giải pháp của Borut và nó cũng hoàn thành điều tương tự. Nhưng có, cả hai đều hoạt động tuyệt vời. :)
Jonathan Zhan

thực sự quá sức khi phải viết mã cho một nhiệm vụ cơ bản như vậy.
Có thể Poyrazoğlu

3
Bạn có thể đạt được cùng một mục tiêu 100% mà không cần mã bằng cách thêm titleLabel.textAlignment Thuộc tính thời gian chạy do người dùng xác định trong Trình tạo giao diện và đặt nó thành Number = 1 (giá trị của NSTextAlignmentCenter).
0xced

21
 button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;

button.titleLabel.textAlignment = NSTextAlignmentCenter;

[button setTitle: @"Line1\nLine2" forState: UIControlStateNormal];

Hoàn hảo! Bạn không cần phải chia nhỏ NSStringbên trong setTitle. `` WordWrapping`` đang làm điều này cho bạn!
Alex Cio

Đối với tôi, tôi đã phải tách chuỗi bên trong tiêu đề đã đặt. Nếu không có nó không làm việc
user1960169

9

Để tránh hoàn toàn việc phải chỉnh sửa mã, và do đó cần phải phân loại chế độ xem của bạn, trong Xcode5 trở lên, bạn có thể làm theo đề xuất của Borut Tomazin:

Trong Trình tạo giao diện (hoặc bảng phân cảnh), đặt Ngắt dòng thành Word Wrap. Hơn bạn có thể chèn nhiều dòng tiêu đề. Chỉ cần nhấn phím Option+ Returnđể tạo dòng mới.

và sau đó, trong Thuộc tính thời gian chạy do người dùng xác định, bạn có thể thêm

Đường dẫn chính: titleLabel.textAlignment
Loại:Number
Giá trị:1

Lưu ý: đây có thể không hoàn toàn là "bằng chứng trong tương lai" vì chúng tôi đang dịch UITextAlignmentCenterhằng số thành giá trị số của nó (và hằng số đó có thể thay đổi khi các phiên bản iOS mới được phát hành), nhưng nó có vẻ an toàn trong tương lai gần.


0

Bạn có thể sửa đổi giá trị cần thiết trực tiếp từ Bảng phân cảnh. Chọn nút, đi tới trình kiểm tra danh tính và thêm cặp khóa-giá trị sau trong phần "Thuộc tính thời gian chạy do người dùng xác định":

nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.