Làm cách nào để chia tỷ lệ imageView của UIButton?


81

Tôi đã tạo một phiên bản UIButton có tên là "nút" với một hình ảnh bằng cách sử dụng [UIButton setImage:forState:]. Button.frame lớn hơn kích thước của hình ảnh.

Bây giờ tôi muốn thu nhỏ hình ảnh của nút này. Tôi đã thử thay đổi button.imageView.frame, button.imageView.boundsbutton.imageView.contentMode, nhưng tất cả dường như không hiệu quả.

Bất cứ ai có thể giúp tôi chia tỷ lệ UIButtonimageView của một?

Tôi đã tạo UIButtonnhư thế này:

UIButton *button = [[UIButton alloc] init];
[button setImage:image forState:UIControlStateNormal];

Tôi đã cố gắng chia tỷ lệ hình ảnh như thế này:

button.imageView.contentMode = UIViewContentModeScaleAspectFit;
button.imageView.bounds = CGRectMake(0, 0, 70, 70);

và điều này:

button.imageView.contentMode = UIViewContentModeScaleAspectFit;
button.imageView.frame = CGRectMake(0, 0, 70, 70);

Câu trả lời:


90

Đối với áp phích gốc, đây là giải pháp tôi tìm thấy:

commentButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;

Điều này sẽ cho phép nút của bạn mở rộng theo chiều ngang. Có một thiết lập dọc.

Tôi đã mất vài giờ để tìm ra điều đó (việc đặt tên tài sản rất khó trực quan) nên tôi muốn chia sẻ.


gợi ý tốt! vấn đề của tôi là chia tỷ lệ hình ảnh kéo dài để thay đổi kích thước của nút bên trái phụ thuộc vào tiêu đề của nó.
Valerii Pavlov,

1
Điều này hoạt động nhưng sẽ không vẽ ra ngoài giới hạn, hãy nghĩ về nó giống như căn chỉnh văn bản trong một dòng mà bạn sẽ không có bất kỳ thứ gì vượt qua lề. Vì vậy, bạn sẽ không nhận được hiệu ứng như UIViewContentModeScaleAspectFill (với một số phần của hình ảnh bị cắt) từ hiệu ứng này.
Hlung

66

Tôi đã gặp phải vấn đề tương tự, trong đó tôi có một Hình nền (một hình có đường viền) và một hình ảnh (cờ) cho một nút tùy chỉnh. Tôi muốn cờ được thu nhỏ và ở giữa. Tôi đã thử thay đổi thuộc tính của imageView nhưng không thành công và thấy hình ảnh này -

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

Trong quá trình thử nghiệm của mình, tôi đã thử:

button.imageEdgeInsets = UIEdgeInsetsMake(kTop,kLeft,kBottom,kRight)

Tôi đã đạt được kết quả mong đợi là:

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


42

Một cách bổ sung cho cấu hình trong tệp XIB. Bạn có thể chọn tùy chọn này nếu bạn muốn văn bản hoặc hình ảnh được Quy mô đầy đủ điền vào UIButton. Nó sẽ giống nhau với mã.

UIButton *btn = [UIButton new];

btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
btn.contentVerticalAlignment   = UIControlContentVerticalAlignmentFill;

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


Nếu bạn muốn kéo dài hình ảnh cho UIButton thì bạn có thể sử dụng thêm hỗ trợ của nội dung hình ảnh và Cắt hình ảnh này. developer.apple.com/library/ios/recipes/…
Linh Nguyen

Thậm chí không biết về phương pháp này. Rock on
Michael McKenna

23

sử dụng

button.contentMode = UIViewContentModeScaleToFill;

không phải

button.imageView.contentMode = UIViewContentModeScaleAspectFit;

Cập nhật:

Như @Chris đã nhận xét,

Để điều này hoạt động cho setImage: forState :, bạn cần làm như sau để chia tỷ lệ theo chiều ngang: myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;


3
Điều này hoạt động tuyệt vời khi kết hợp với [button setBackgroundImage: forState:]. Cảm ơn.
Jason DeFontes

Ghi lại chính xác những gì Jason nói và bạn sẽ tốt. Nó không làm việc cho setImage: forState:
dpjanes

7
Để điều này hoạt động cho setImage: forState :, bạn cần làm như sau để chia tỷ lệ theo chiều ngang: myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
Chris

15
    UIButton *button= [[UIButton alloc] initWithFrame:CGRectMake(0,0,70,70)];
    button.buttonType = UIButtonTypeCustom;
    UIImage *buttonImage = [UIImage imageNamed:@"image.png"];

    UIImage *stretchableButtonImage = [buttonImage stretchableImageWithLeftCapWidth:12 topCapHeight:0]; 
    [button setBackgroundImage:stretchableButtonImage forState:UIControlStateNormal]; 

@EEE Cảm ơn bạn. Nhưng có 2 vấn đề: 1. Câu hỏi của tôi là sử dụng biến _imageView của UIButton, không phải biến _backgroundView. Tôi có phải làm điều đó với backgroundView không? 2. chức năng [UIImage stretchableImageWithLeftCapWidth: topCapHeight:] chỉ có thể làm cho hình ảnh lớn hơn, nhưng không thể làm cho hình ảnh nhỏ hơn. Cảm ơn tất cả, và câu trả lời của bạn giải quyết một câu hỏi khác của tôi: Tôi muốn vẽ tiêu đề trên nút với hình ảnh phía sau. Tôi nghĩ _backgroundImage có thể giúp tôi. Câu hỏi này có câu trả lời khác tốt hơn không?
vcLwei

Tôi thấy những gì bạn đang cố gắng làm và đây là cách. nếu hình ảnh của bạn lớn hơn, hãy thay đổi kích thước hình ảnh đó bằng một công cụ và mọi thứ bạn muốn sẽ được thực hiện. Đừng lãng phí thời gian của bạn với_imageview. Bằng cách này nếu bạn thích asnwer này, bạn có thể bỏ phiếu nó lên, và chấp nhận nó
EEE

Bạn có thể thay đổi kích thước hình ảnh của mình trong chương trình Xem trước trong MacOS. Chỉ cần mở công cụ chụp ảnh và chụp ảnh -> Điều chỉnh kích thước
EEE

@EEE Có, tôi có thể thay đổi kích thước hình ảnh của mình bằng một công cụ. Nhưng trong ứng dụng của tôi đôi khi tôi cũng cần hình ảnh lớn hơn, tôi không muốn hai hình ảnh giống nhau chỉ khác nhau về kích thước, như vậy quá lãng phí dung lượng. Và một cách khác để giải quyết câu hỏi của tôi là tôi có thể sử dụng CGBitmapContext để có được hình ảnh nhỏ hơn, nhưng tôi đoán cách này gây bất tiện so với việc sử dụng _imageview. Lý do tôi không bình chọn nó là danh tiếng của tôi ít hơn 15, thực sự tôi rất muốn làm điều đó. Cảm ơn!
vcLwei

10

Tôi đã tìm thấy giải pháp này.

1) Phân lớp các phương thức sau của UIButton

+ (id)buttonWithType:(UIButtonType)buttonType {
    MyButton *toReturn = [super buttonWithType:buttonType];
    toReturn.imageView.contentMode = UIViewContentModeScaleAspectFit;
    return toReturn;
}

- (CGRect)imageRectForContentRect:(CGRect)contentRect {
    return contentRect;
}

Và nó hoạt động tốt.


- (CGRect) backgroundRectForBounds: giới hạn (CGRect), dành cho hình nền.
Ricky

9

Lạ thay, kết hợp duy nhất phù hợp với tôi (iOS 5.1) là ...

button.imageView.contentMode = UIViewContentModeScaleAspectFit;

[button setImage:newImage forState:UIControlStateNormal];


Ban đầu tôi sử dụng: button.contentMode = UIViewContentModeScaleAspectFit; bây giờ tôi cũng cần viết button.imageView.contentMode = UIViewContentModeScaleAspectFit; để giữ tỉ lệ trên iPad 3 võng mạc
Enrico Detoma


7

Chỉ cần làm (Từ Thiết kế HOẶC Từ Mã):

Từ thiết kế

  1. Mở xib HOẶC Bảng phân cảnh của bạn.
  2. Nút chọn
  3. Bên trong Trình kiểm tra thuộc tính (Bên phải)> Trong phần "Điều khiển" > chọn tùy chọn thứ 4 cuối cùng cho cả Ngang và Verical.

[Đối với Điểm # 3: Thay đổi Căn chỉnh ngang và dọc thành UIControlContentHorizontalAlignmentFill and UIControlContentVericalAlignmentFill]

Từ mã

button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment =  UIControlContentVerticalAlignmentFill;

5

như thế này có thể giải quyết vấn đề của bạn:

+ (UIImage*)resizedImage:(UIImage*)image
{
 CGRect frame = CGRectMake(0, 0, 60, 60);
 UIGraphicsBeginImageContext(frame.size);
 [image drawInRect:frame];
 UIImage* resizedImage = UIGraphicsGetImageFromCurrentImageContext();
 UIGraphicsEndImageContext();

 return resizedImage;
}

5

Từ thử nghiệm nhỏ mà tôi vừa thực hiện sau khi đọc ở đây, tùy thuộc vào việc bạn sử dụng setImage hay setBackgroundImage, cả hai đều cho kết quả giống nhau và kéo giãn hình ảnh

//for setBackgroundImage
 self.imageButton.contentMode = UIViewContentModeScaleAspectFill;
        [self.imageButton setBackgroundImage:[UIImage imageNamed:@"imgFileName"] forState:UIControlStateNormal];

//for setImage
 self.imageButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
        self.imageButton.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
    [self.imageButton setImage:[UIImage imageNamed:@"imgFileName"] forState:UIControlStateNormal];

nhờ một tấn ... giải pháp hoàn hảo cho phù hợp hình ảnh nhỏ kích thước nhỏ hơn kích thước sau đó nút ...
Fahim Parkar

4
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment =  UIControlContentVerticalAlignmentFill;

2

Điều này cũng sẽ hoạt động, vì backgroundImage tự động thay đổi tỷ lệ

[button setBackgroundImage:image forState:UIControlStateNormal];


2

Bảng phân cảnh

Bạn phải xác định thuộc tính cụ thể trong Thuộc tính thời gian chạy của trình kiểm tra danh tính - imageView.contentModel, nơi bạn đặt giá trị tương đối với rawValuevị trí của enum UIViewContentMode. 1 có nghĩa là scaleAspectFit .

Đặt button.imageView.contentMode trong Storyboard

Và căn chỉnh của nút, trong trình kiểm tra Thuộc tính :

Căn chỉnh hoàn toàn của nút


1

Tôi không thể sử dụng giải pháp bằng _imageView, nhưng tôi có thể sử dụng một CGContextRefgiải pháp để giải quyết nó. Nó sử dụng UIGraphicsGetCurrentContextđể lấy currentContextRef và vẽ một hình ảnh trong currentContextRef, sau đó chia tỷ lệ hoặc xoay hình ảnh và tạo một hình ảnh mới. Nhưng nó không hoàn hảo.

mật mã:

-(UIImage*) scaleAndRotateImage:(UIImage*)photoimage width:(CGFloat)bounds_width height:(CGFloat)bounds_height;
{
    CGImageRef imgRef = photoimage.CGImage;

    CGFloat width = CGImageGetWidth(imgRef);
    CGFloat height = CGImageGetHeight(imgRef);

    CGAffineTransform transform = CGAffineTransformIdentity;
    CGRect bounds = CGRectMake(0, 0, width, height);

    bounds.size.width = bounds_width;
    bounds.size.height = bounds_height;

    CGFloat scaleRatio = bounds.size.width / width;
    CGFloat scaleRatioheight = bounds.size.height / height;
    CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
    CGFloat boundHeight;
    UIImageOrientation orient = photoimage.imageOrientation;
    switch(orient)
    {
        case UIImageOrientationUp: //EXIF = 1
            transform = CGAffineTransformIdentity;
            break;

        case UIImageOrientationUpMirrored: //EXIF = 2
            transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            break;

        case UIImageOrientationDown: //EXIF = 3
            transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;

        case UIImageOrientationDownMirrored: //EXIF = 4
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
            transform = CGAffineTransformScale(transform, 1.0, -1.0);
            break;

        case UIImageOrientationLeftMirrored: //EXIF = 5
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationLeft: //EXIF = 6
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationRightMirrored: //EXIF = 7
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeScale(-1.0, 1.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        case UIImageOrientationRight: //EXIF = 8
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        default:
            [NSException raise:NSInternalInconsistencyException format:@"Invalid?image?orientation"];
            break;
    }

    UIGraphicsBeginImageContext(bounds.size);

    CGContextRef context = UIGraphicsGetCurrentContext();

    if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft)
    {
        CGContextScaleCTM(context, -scaleRatio, scaleRatioheight);
        CGContextTranslateCTM(context, -height, 0);
    }
    else
    {
        CGContextScaleCTM(context, scaleRatio, -scaleRatioheight);
        CGContextTranslateCTM(context, 0, -height);
    }

    CGContextConcatCTM(context, transform);

    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return imageCopy;
}

1

Tôi hy vọng điều này có thể giúp ích cho ai đó khác:

Swift 3+

button.contentHorizontalAlignment = UIControlContentHorizontalAlignment.fill
button.contentVerticalAlignment =  UIControlContentVerticalAlignment.fill


-1

Mỗi UIButton đều có một UIImageView ẩn của riêng nó. Vì vậy chúng ta phải thiết lập chế độ nội dung như cách dưới đây ...

[[btn imageView] setContentMode: UIViewContentModeScaleAspectFit];
[btn setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];

-1

Ảnh chụp màn hình trong XCode 8

Ở dưới cùng bên trái của ảnh chụp màn hình, bạn có thể thấy thuộc tính Kéo dài. Hãy thử sử dụng chúng.

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.