Tôi đến bữa tiệc muộn một chút, nhưng tôi nghĩ rằng tôi có một cái gì đó hữu ích để thêm vào.
Câu trả lời của Kekoa rất hay nhưng, như RonLugge đề cập, nó có thể khiến nút không còn tôn trọng sizeToFit
hoặc quan trọng hơn, có thể khiến nút này cắt nội dung của nó khi nó có kích thước thực sự. Rất tiếc!
Đầu tiên, mặc dù,
Một lời giải thích ngắn gọn về cách tôi tin imageEdgeInsets
và titleEdgeInsets
làm việc:
Các tài liệu choimageEdgeInsets
có những điều sau đây để nói, một phần:
Sử dụng thuộc tính này để thay đổi kích thước và định vị lại hình chữ nhật vẽ hiệu quả cho hình ảnh nút. Bạn có thể chỉ định một giá trị khác nhau cho mỗi trong số bốn phần tử (trên cùng, bên trái, dưới cùng, bên phải). Một giá trị dương co lại, hoặc chèn vào, cạnh đó di chuyển nó đến gần trung tâm của nút. Một giá trị âm mở rộng, hoặc đặt ra, cạnh đó.
Tôi tin rằng tài liệu này được viết tưởng tượng rằng nút không có tiêu đề, chỉ là một hình ảnh. Nó có ý nghĩa hơn rất nhiều khi nghĩ về cách này, và hành xử như thế nào UIEdgeInsets
thường làm. Về cơ bản, khung của hình ảnh (hoặc tiêu đề, với titleEdgeInsets
) được di chuyển vào trong cho các phần tử dương và hướng ra ngoài cho các phần tử âm.
Được, vậy thì sao?
Tôi đang đến đó! Đây là những gì bạn có theo mặc định, đặt hình ảnh và tiêu đề (viền nút chỉ màu xanh lá cây để hiển thị vị trí của nó):
Khi bạn muốn khoảng cách giữa một hình ảnh và một tiêu đề, mà không làm cho bị nghiền nát, bạn cần đặt bốn phần tử khác nhau, hai phần trên mỗi hình ảnh và tiêu đề. Đó là bởi vì bạn không muốn thay đổi kích thước của các khung đó, mà chỉ là vị trí của chúng. Khi bạn bắt đầu nghĩ theo cách này, sự thay đổi cần thiết cho danh mục xuất sắc của Kekoa trở nên rõ ràng:
@implementation UIButton(ImageTitleCentering)
- (void)centerButtonAndImageWithSpacing:(CGFloat)spacing {
CGFloat insetAmount = spacing / 2.0;
self.imageEdgeInsets = UIEdgeInsetsMake(0, -insetAmount, 0, insetAmount);
self.titleEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, -insetAmount);
}
@end
Nhưng chờ đã , bạn nói, khi tôi làm điều đó, tôi nhận được điều này:
Ồ vâng! Tôi quên mất, các tài liệu đã cảnh báo tôi về điều này. Họ nói, một phần:
Thuộc tính này chỉ được sử dụng để định vị hình ảnh trong khi bố trí. Nút không sử dụng thuộc tính này để xác định intrinsicContentSize
và sizeThatFits:
.
Nhưng có là một tài sản có thể giúp, và rằng nhân contentEdgeInsets
. Các tài liệu cho rằng, một phần:
Nút sử dụng thuộc tính này để xác định intrinsicContentSize
và sizeThatFits:
.
Điều đó nghe có vẻ tốt. Vì vậy, hãy điều chỉnh danh mục một lần nữa:
@implementation UIButton(ImageTitleCentering)
- (void)centerButtonAndImageWithSpacing:(CGFloat)spacing {
CGFloat insetAmount = spacing / 2.0;
self.imageEdgeInsets = UIEdgeInsetsMake(0, -insetAmount, 0, insetAmount);
self.titleEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, -insetAmount);
self.contentEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, insetAmount);
}
@end
Và bạn nhận được gì?
Trông như một người thắng cuộc đối với tôi.
Làm việc trong Swift và không muốn suy nghĩ gì cả? Đây là phiên bản cuối cùng của tiện ích mở rộng trong Swift:
extension UIButton {
func centerTextAndImage(spacing: CGFloat) {
let insetAmount = spacing / 2
imageEdgeInsets = UIEdgeInsets(top: 0, left: -insetAmount, bottom: 0, right: insetAmount)
titleEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount, bottom: 0, right: -insetAmount)
contentEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount, bottom: 0, right: insetAmount)
}
}