UIButton sẽ không chuyển đến Aspect Fit trong iPhone


105

Tôi có một vài UIButtons và trong IB chúng được đặt thành Aspect Fit, nhưng vì một số lý do mà chúng luôn căng ra. Có điều gì khác bạn phải thiết lập không? Tôi đã thử tất cả các chế độ xem khác nhau và không có chế độ nào hoạt động, tất cả chúng đều căng ra.


Câu trả lời của @Werner Altesischer là đúng. Thực hiện các thay đổi thích hợp.
Harshit Gupta

1
@marty Bạn đang đặt hình nền hay hình ảnh? hình nền không hỗ trợ nó, chỉ hình ảnh.
Juan Boero

Câu trả lời:


45

Tôi đã gặp vấn đề đó trước đây. Tôi đã giải quyết nó bằng cách đưa hình ảnh của mình vào một UIImageView, nơi contentModecài đặt thực sự hoạt động và đặt một tùy chỉnh trong suốt UIButtonlên trên đó.

CHỈNH SỬA: Câu trả lời này đã lỗi thời. Xem câu trả lời của @Werner Altewischer để biết câu trả lời chính xác trong các phiên bản iOS hiện đại.


Yeah đã thử điều đó, nhưng bây giờ không thể nhận được nút để chỉnh sửa lại hình ảnh
Marty 11/10/10

Làm thế nào để bạn quản lý các trạng thái nút với kỹ thuật này? Có vẻ như phản hồi tương tác của người dùng như "được đánh dấu" sẽ là một cơn ác mộng.
SooDesuNe 24/10/12

3
Đây có thể là cách đúng để làm điều này cách đây 2,5 năm khi câu hỏi này được trả lời, nhưng bây giờ bạn có thể chỉnh sửa ImageView nội bộ của UIButton và đặt chế độ nội dung ở đó. Xem câu trả lời của @Werner Altewischer
Steve Haley

233

Giải pháp là đặt contentModetrên thuộc imageViewtính của UIButton. Các UIButtonđã được tạo ra với kiểu tùy chỉnh để làm việc này tôi tin rằng (nếu không nilđược trả lại cho thuộc tính này).


67
Điều này đã làm việc cho tôi:[button.imageView setContentMode:UIViewContentModeScaleAspectFit];
ayreguitar

2
Điều này cũng phù hợp với tôi nhưng nếu tôi đặt AdjustsImageWhenHighlighted = YES, hình ảnh sẽ bị kéo dài trở lại khi tôi nhấn vào nút.
cduck

1
Sự kéo căng trong adjustsImage đã được loại bỏ trong iOS 6.
Bến Flynn

3
Trong iOS 8, điều này thực sự không hoạt động với tôi. Câu trả lời ban đầu (với việc đặt imageView sau một nút trong suốt) hoạt động tốt nhất.
user1416564,

3
trong Swift du jour:button.imageView!.contentMode = UIViewContentMode.scaleAspectFit
Nestor

57

Phương pháp này rất hiệu quả với tôi.:

Trong Xib, chọn nút và đặt user defined runtime attributes:

  • Đường dẫn chính: self.imageView.contentMode
  • Kiểu: Number
  • Giá trị: 1

Bấm vào đây để xem rõ hơn giải pháp

Chúng tôi sử dụng số vì bạn không thể sử dụng enum ở đó. Nhưng UIViewContentModeScaleAspectFit bằng 1.


2
Điều này cũng cập nhật hình ảnh trong trình tạo giao diện trong thời gian thiết kế. Giải pháp tuyệt vời.
George Filippakos

Giải pháp tuyệt vời, ít mã và hoạt động giống như một sự quyến rũ, enum dựa trên các mục danh sách chế độ nội dung.
Kross

Bạn cũng có thể thêm tiện ích mở rộng để làm cho nó dễ dàng hơn một chút: extension UIButton { @IBInspectable var imageContentMode: Int { get {return imageView?.contentMode.rawValue ?? 0} set {imageView?.contentMode = UIViewContentMode(rawValue: newValue) ?? .scaleAspectFit} } }
Yonat 12/1217

Không có 'bản thân' imageView.contentModeđã làm việc cho tôi!
byJeevan

22

Nếu bạn đang thực hiện việc này trong Trình tạo giao diện, bạn có thể sử dụng trình kiểm tra thuộc tính Thời gian chạy để đặt điều này trực tiếp mà không cần bất kỳ mã nào.

Đặt Đường dẫn khóa của bạn trên nút thành "imageView.contentMode" với loại "Số" và giá trị "1" (hoặc bất kỳ chế độ nào bạn muốn).

imageview.contentMode = 1


14

Sử dụng imageView của nút cho contentMode. Không trực tiếp trên chính nút.

homeButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
homeButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
homeButton.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
[homeButton setImage:[UIImage imageNamed:kPNGLogo] forState:UIControlStateNormal];

6

Nếu bạn đặt hình ảnh vào UIImageViewphía sau nút, bạn sẽ mất chức năng tích hợp của UIButtonlớp, chẳng hạn như adjustsImageWhenHighlightedadjustsImageWhenDisabled, và tất nhiên là khả năng đặt các hình ảnh khác nhau cho các trạng thái khác nhau (mà không cần phải tự làm điều này).

Nếu chúng ta muốn xóa hình ảnh cho tất cả các trạng thái điều khiển , một điều khó khăn là lấy hình ảnh bằng cách sử dụng imageWithCGImage:scale:orientation, như trong phương pháp sau:

- (UIImage *) getScaledImage:(UIImage *)img insideButton:(UIButton *)btn {

    // Check which dimension (width or height) to pay respect to and
    // calculate the scale factor
    CGFloat imgRatio = img.size.width / img.size.height, 
            btnRatio = btn.frame.size.width / btn.frame.size.height,
            scaleFactor = (imgRatio > btnRatio 
                           ? img.size.width / btn.frame.size.width
                           : img.size.height / btn.frame.size.height;

    // Create image using scale factor
    UIImage *scaledImg = [UIImage imageWithCGImage:[img CGImage]
                                             scale:scaleFactor
                                       orientation:UIImageOrientationUp];
    return scaledImg;
}

Để thực hiện điều này, chúng tôi sẽ viết:

UIImage *scaledImg = [self getScaledImage:myBtnImg insideButton:myBtn];
[myBtn setImage:scaledImg forState:UIControlStateNormal];

Điều này sẽ ngăn hình ảnh bị kéo dài ở tất cả các trạng thái điều khiển. Nó hiệu quả với tôi, nhưng hãy cho tôi biết nếu nó không hiệu quả!

LƯU Ý: Ở đây chúng tôi đang giải quyết một vấn đề liên quan đến UIButton, nhưng insideButton:cũng có thể là insideView:, hoặc bất cứ điều gì mà người ta muốn để phù hợp với hình ảnh.


6

Tôi đã gặp vấn đề này một thời gian trở lại. Vấn đề tôi gặp phải là tôi đang cố gắng áp dụng hiệu ứng này cho UIButton nền bị hạn chế và do đó có nghĩa là bạn không thể điều chỉnh nó dễ dàng.

Bí quyết là đặt nó chỉ là một hình ảnh sau đó áp dụng kỹ thuật của @ ayreguitar và điều đó sẽ khắc phục được!

UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];
[myButton setContentMode:UIViewContentModeScaleAspectFill];
[myButton setImage:@"myImage.png" forState:UIControlStateNormal];

4

Điều này đã làm việc cho tôi

[button.imageView setContentMode:UIViewContentModeScaleAspectFit];

Cảm ơn @ayreguitar vì nhận xét của anh ấy


4

Đây là một câu trả lời thay thế nhanh chóng:

myButton.imageView?.contentMode = .ScaleAspectFit

4

Kết hợp một số câu trả lời khác nhau thành một giải pháp - tạo một nút với loại tùy chỉnh, đặt thuộc tính imageView contentMode của nút và đặt hình ảnh cho nút (không phải hình nền, vẫn sẽ chia tỷ lệ để lấp đầy).

//Objective-C:
UIImage *image = [UIImage imageNamed:"myImageName.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:image forState:UIControlStateNormal];
button.imageView.contentMode = UIViewContentModeScaleAspectFit;

//Swift:
let image = UIImage(named: "myImageName.png")
let button = UIButton(type: .custom)
button.imageView?.contentMode = .scaleAspectFit
button.setImage(image, for: .normal)

3
btn.imageView.contentMode = UIViewContentModeScaleAspectFit;

Mặc dù đoạn mã này có thể giải quyết câu hỏi, bao gồm một lời giải thích thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho người đọc trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn. - Từ đánh giá
Ferrybig

2

Câu trả lời này dựa trên câu trả lời của @ WernerAltewischer .

Để tránh phải kết nối nút của tôi với IBOutlet để thực thi mã trên nó, tôi đã phân loại lớp của UIButton:

// .h
@interface UIButtonWithImageAspectFit : UIButton
@end

// .m
@implementation UIButtonWithImageAspectFit

- (void) awakeFromNib {
    [self.imageView setContentMode:UIViewContentModeScaleAspectFit];
}

@end



Bây giờ, hãy tạo một nút tùy chỉnh trong xib của bạn và đặt hình ảnh của nó (không phải hình nền):

UIButtonWithImageAspectFit: tạo và đặt hình ảnh


Sau đó, đặt lớp của nó:

UIButtonWithImageAspectFit: đặt lớp tùy chỉnh

Bạn đã hoàn tất!
Thay vì
UIButton không phù hợp với khía cạnh hình ảnh
phù hợp với khía cạnh hình ảnh của nút của bạn bây giờ như mong đợi:
UIButton phù hợp với khía cạnh hình ảnh


2

ios 12. Bạn cũng cần thêm Căn chỉnh nội dung

class FitButton: UIButton {

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)


    }

    override func layoutSubviews() {
        self.imageView?.contentMode = .scaleAspectFill
        self.contentHorizontalAlignment = .fill
        self.contentVerticalAlignment = .fill
        super.layoutSubviews()


    }

}

1

Tôi đã gặp vấn đề với hình ảnh không thay đổi kích thước tương xứng nên cách tôi sửa nó là sử dụng các tấm lót cạnh.

fooButton.contentEdgeInsets = UIEdgeInsetsMake(10, 15, 10, 15);

1

Chế độ nội dung UIView áp dụng cho "nội dung" của CALayer tương ứng. Điều này hoạt động cho UIImageViews vì họ đặt CALayernội dung tương ứng CGImage.

drawRect: cuối cùng hiển thị nội dung lớp.

Một tùy chỉnh UIButton(theo như tôi biết) không có nội dung (các nút kiểu chữ nhật tròn có thể được hiển thị bằng nội dung). Nút có các lượt xem phụ: nền UIImageView, hình ảnh UIImageViewvà tiêu đề UILabel. Đặt chế độ xem phụ contentModecó thể làm những gì bạn muốn, nhưng việc xáo trộn UIButtonhệ thống phân cấp chế độ xem là một việc không nên.


1

Thay đổi UIButton.imageView.contentModekhông hiệu quả với tôi.
Tôi đã giải quyết vấn đề bằng cách đặt hình ảnh thành thuộc tính 'Nền'.
Bạn có thể thêm ràng buộc tỷ lệ nếu bạn cần


1

Điều này trùng lặp với nhiều câu trả lời khác, nhưng giải pháp cho tôi là

  • thiết lập contentModecủa UIImageViewcác nút để .ScaleAspectFit- mà có thể được thực hiện trong “User Defined Runtime Thuộc tính” trong giao diện Builder (ví dụ. self.imageView.contentMode, Number, 1) hoặc trong mộtUIButton lớp con;
  • vô hiệu hóa "Tự động kích thước lượt xem phụ";
  • đặt "Edge" thành "Image" và các giá trị "Top" và "Bottom" thích hợp cho "Inset" (có thể chỉ cần thiết nếu bạn, như tôi, sử dụng PDF làm hình ảnh).

0

Bạn có thể sử dụng imageWithCGImage như hình trên (nhưng không có dấu ngoặc đơn).

Ngoài ra ... hàng triệu điện thoại không phải 4.0 sẽ không hoạt động với mã đó.



0

Tương tự như @Guillaume, tôi đã tạo một lớp con của UIButton dưới dạng Swift-File. Sau đó, đặt lớp tùy chỉnh của tôi trong Trình tạo giao diện:

người xây dựng giao diện.

Và đây là tệp Swift:

import UIKit

class TRAspectButton : UIButton {
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.imageView?.contentMode = .ScaleAspectFit
    }
}

-1

Tôi đã gặp vấn đề tương tự, nhưng tôi không thể làm cho nó hoạt động (có lẽ đó là một lỗi với SDK).

Cuối cùng, như một cách giải quyết, tôi đã đặt một UIImageViewnút phía sau nút của mình và đặt các tùy chọn tôi muốn trên đó, sau đó chỉ cần đặt một khoảng trống UIButtonlên trên nó.


7
Có một tiếng vang ở đây? ;-)
Dan Ray
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.