UIButton จะไม่ไปที่ Aspect Fit ใน iPhone


106

ฉันมี UIButtons สองสามปุ่มและใน IB พวกเขาถูกตั้งค่าเป็น Aspect Fit แต่ด้วยเหตุผลบางอย่างพวกเขามักจะยืดออก คุณต้องตั้งค่าอย่างอื่นหรือไม่? ฉันลองใช้โหมดมุมมองที่แตกต่างกันทั้งหมดแล้ว แต่ก็ไม่มีอะไรทำงานเลย


คำตอบของ @Werner Altesischer คือคำตอบที่ถูกต้อง ทำการเปลี่ยนแปลงที่เหมาะสม
Harshit Gupta

1
@marty คุณกำลังตั้งค่าภาพพื้นหลังหรือภาพ? ภาพพื้นหลังไม่รองรับภาพเท่านั้น
Juan Boero

คำตอบ:


45

ฉันเคยมีปัญหานั้นมาก่อน ฉันแก้ไขได้โดยใส่รูปภาพของฉันในUIImageViewตำแหน่งที่contentModeการตั้งค่าใช้งานได้จริงและวางค่ากำหนดเองแบบโปร่งใสUIButtonไว้ด้านบน

แก้ไข: คำตอบนี้ล้าสมัย ดูคำตอบของ @Werner Altewischerสำหรับคำตอบที่ถูกต้องใน iOS เวอร์ชันใหม่


ใช่ลองแล้ว แต่ตอนนี้ไม่สามารถรับปุ่มเพื่อปรับแต่งรูปภาพได้
พลีชีพ

คุณจัดการสถานะปุ่มด้วยเทคนิคนี้อย่างไร? ดูเหมือนว่าการตอบสนองต่อการโต้ตอบของผู้ใช้เช่น "ไฮไลต์" จะเป็นฝันร้าย
SooDesuNe

3
นี่อาจเป็นวิธีที่ถูกต้องในการทำสิ่งนี้เมื่อ 2.5 ปีก่อนเมื่อคำถามนี้ได้รับคำตอบ แต่ตอนนี้คุณสามารถแก้ไข ImageView ภายในของ UIButton และตั้งค่าโหมดเนื้อหาได้ที่นั่น ดูคำตอบโดย @Werner Altewischer
Steve Haley

235

การแก้ปัญหาคือการตั้งค่าcontentModeในทรัพย์สินของimageView จะต้องมีการสร้างขึ้นด้วยประเภทที่กำหนดเองสำหรับการทำงานผมเชื่อว่า (มิฉะนั้นจะถูกส่งกลับสำหรับคุณสมบัตินี้)UIButtonUIButtonnil


68
สิ่งนี้ใช้ได้ผลสำหรับฉัน:[button.imageView setContentMode:UIViewContentModeScaleAspectFit];
ayreguitar

2
สิ่งนี้ใช้ได้กับฉันเช่นกัน แต่ถ้าฉันตั้งค่า adjustsImageWhenHighlighted = YES ภาพจะยืดออกอีกครั้งเมื่อฉันแตะที่ปุ่ม
cduck

1
การยืดในการปรับภาพได้ถูกตัดออกใน iOS 6
Ben Flynn

3
ใน iOS 8 สิ่งนี้ใช้ไม่ได้กับฉัน คำตอบเดิม (ด้วยการวาง imageView ไว้ด้านหลังปุ่มโปร่งใส) จะทำงานได้ดีที่สุด
user1416564

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

58

วิธีนี้ใช้ได้ผลดีกับฉันมาก:

ในXibเลือกปุ่มและตั้งค่าuser defined runtime attributes:

  • เส้นทางสำคัญ: self.imageView.contentMode
  • ประเภท: Number
  • มูลค่า: 1

คลิกที่นี่เพื่อดูวิธีแก้ปัญหาอย่างชัดเจนยิ่งขึ้น

เราใช้หมายเลขเพราะคุณไม่สามารถใช้ enum ที่นั่นได้ แต่ UIViewContentModeScaleAspectFit เท่ากับ 1


2
นอกจากนี้ยังอัปเดตรูปภาพในตัวสร้างอินเทอร์เฟซในช่วงเวลาออกแบบ ทางออกที่ดี
George Filippakos

ทางออกที่ดีรหัสไม่กี่และใช้งานได้เหมือนมีเสน่ห์ enum จะขึ้นอยู่กับรายการในโหมดเนื้อหา
Kross

คุณสามารถเพิ่มส่วนขยายเพื่อให้ง่ายขึ้น: extension UIButton { @IBInspectable var imageContentMode: Int { get {return imageView?.contentMode.rawValue ?? 0} set {imageView?.contentMode = UIViewContentMode(rawValue: newValue) ?? .scaleAspectFit} } }
Yonat

ไม่มี 'ตัวเอง' imageView.contentModeทำงานให้ฉัน!
Jeevan

22

หากคุณทำสิ่งนี้ใน Interface Builder คุณสามารถใช้ตัวตรวจสอบแอตทริบิวต์ Runtime เพื่อตั้งค่านี้ได้โดยตรงโดยไม่ต้องใช้รหัสใด ๆ

ตั้งค่า Key Path บนปุ่มเป็น "imageView.contentMode" ด้วยประเภท "Number" และค่า "1" (หรือโหมดใดก็ได้ที่คุณต้องการ)

imageview.contentMode = 1


14

ใช้ imageView ของปุ่มสำหรับ contentMode ไม่ได้อยู่ที่ปุ่มโดยตรง

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

6

หากคุณวางภาพUIImageViewไว้ด้านหลังปุ่มคุณจะสูญเสียฟังก์ชันการทำงานในตัวของUIButtonคลาสเช่นadjustsImageWhenHighlightedและadjustsImageWhenDisabledและแน่นอนความสามารถในการตั้งค่าภาพที่แตกต่างกันสำหรับสถานะที่แตกต่างกัน (โดยไม่ต้องทำสิ่งนี้ด้วยตัวเอง)

หากเราต้องการให้ภาพที่ไม่มีการตรึงสำหรับสถานะการควบคุมทั้งหมด approuch หนึ่งคือการรับภาพโดยใช้imageWithCGImage:scale:orientationวิธีการต่อไปนี้:

- (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;
}

ในการดำเนินการนี้เราจะเขียน:

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

สิ่งนี้ควรป้องกันไม่ให้ภาพยืดออกในสถานะควบคุมทั้งหมด มันได้ผลสำหรับฉัน แต่โปรดแจ้งให้เราทราบหากไม่ได้ผล!

หมายเหตุ: ที่นี่เรากำลังแก้ไขปัญหาที่เกี่ยวข้องUIButtonแต่insideButton:อาจเป็นเช่นกันinsideView:หรืออะไรก็ได้ที่ต้องการให้พอดีกับภาพ


6

ฉันมีปัญหานี้อยู่ครู่หนึ่ง ปัญหาที่ฉันพบคือฉันพยายามใช้เอฟเฟกต์นี้กับ UIButton พื้นหลังซึ่งมีข้อ จำกัด ดังนั้นคุณจึงไม่สามารถปรับได้อย่างง่ายดาย

เคล็ดลับคือตั้งเป็นแค่ภาพจากนั้นใช้เทคนิคของ @ ayreguitar และควรแก้ไข!

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



4

การรวมคำตอบที่แตกต่างกันสองสามคำเข้าด้วยกันในโซลูชันเดียว - สร้างปุ่มด้วยประเภทที่กำหนดเองตั้งค่าคุณสมบัติ imageView contentMode ของปุ่มและตั้งค่ารูปภาพสำหรับปุ่ม (ไม่ใช่ภาพพื้นหลังซึ่งจะยังคงปรับขนาดเพื่อเติมเต็ม)

//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;

แม้ว่าข้อมูลโค้ดนี้จะช่วยแก้ปัญหาได้ แต่การอธิบายจะช่วยปรับปรุงคุณภาพของโพสต์ของคุณได้มาก โปรดจำไว้ว่าคุณกำลังตอบคำถามสำหรับผู้อ่านในอนาคตและบุคคลเหล่านั้นอาจไม่ทราบสาเหตุของการแนะนำโค้ดของคุณ - จากรีวิว
Ferrybig

2

คำตอบนี้จะขึ้นอยู่กับ@ คำตอบของ

เพื่อหลีกเลี่ยงการเชื่อมต่อปุ่มของฉันเข้ากับ IBOutlet เพื่อรันโค้ดบนนั้นฉันเลือกคลาสของ UIButton คลาสย่อย:

// .h
@interface UIButtonWithImageAspectFit : UIButton
@end

// .m
@implementation UIButtonWithImageAspectFit

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

@end



ตอนนี้สร้างปุ่มที่กำหนดเองใน xib ของคุณและตั้งค่าภาพ (ไม่ใช่ภาพพื้นหลัง):

UIButtonWithImageAspectFit: สร้างและตั้งค่ารูปภาพ


จากนั้นตั้งค่าระดับ:

UIButtonWithImageAspectFit: ตั้งค่าคลาสที่กำหนดเอง

เสร็จแล้ว!
แทนที่จะ
UIButton ไม่พอดีกับภาพ
พอดีกับขนาดภาพของปุ่มของคุณตอนนี้เป็นไปตามที่คาดไว้:
UIButton ที่มีขนาดพอดีกับภาพ


2

iOS 12. คุณต้องเพิ่มการจัดตำแหน่งเนื้อหาด้วย

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

ฉันมีปัญหากับรูปภาพที่ไม่ได้ปรับขนาดตามสัดส่วนดังนั้นวิธีที่ฉันแก้ไขคือการใช้ขอบแทรก

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

1

โหมดเนื้อหา UIView ใช้กับ "เนื้อหา" ของ CALayer ที่เกี่ยวข้อง งานนี้UIImageViewเพราะพวกเขาตั้งค่าเนื้อหาที่สอดคล้องกันCALayerCGImage

drawRect: ในที่สุดก็แสดงผลไปยังเนื้อหาเลเยอร์

กำหนดเองUIButton(เท่าที่ฉันรู้) ไม่มีเนื้อหา (ปุ่มลักษณะสี่เหลี่ยมผืนผ้าโค้งมนอาจแสดงผลโดยใช้เนื้อหา) ปุ่มที่มี subviews: พื้นหลังUIImageViewภาพและชื่อUIImageView UILabelการตั้งค่าcontentModeบนมุมมองย่อยอาจทำในสิ่งที่คุณต้องการ แต่การยุ่งกับUIButtonลำดับชั้นของมุมมองเป็นเรื่องที่ไม่น่าสนใจ


1

การเปลี่ยนUIButton.imageView.contentModeไม่ได้ผลสำหรับฉัน
ฉันแก้ไขปัญหาโดยตั้งค่ารูปภาพเป็นคุณสมบัติ "พื้นหลัง"
คุณสามารถเพิ่มข้อ จำกัด อัตราส่วนได้หากต้องการ


1

สิ่งนี้ทับซ้อนกับคำตอบอื่น ๆ มากมาย แต่วิธีแก้ปัญหาสำหรับฉันคือ

  • ตั้งค่าcontentModeของUIImageViewปุ่มสำหรับ.ScaleAspectFit- ซึ่งสามารถทำได้ใน "User Defined Runtime Attributes" ใน Interface Builder (เช่นself.imageView.contentModeหมายเลข 1) หรือในUIButtonคลาสย่อย
  • ปิดการใช้งาน” Autoresize Subviews”;
  • ตั้งค่า "ขอบ" เป็น "รูปภาพ" และค่า "ด้านบน" และ "ด้านล่าง" ที่เหมาะสมสำหรับ "Inset" (ซึ่งอาจจำเป็นก็ต่อเมื่อคุณใช้ PDF เป็นรูปภาพเช่นฉันเท่านั้น)

0

คุณสามารถใช้ imageWithCGImage ดังที่แสดงด้านบน (แต่ไม่มีวงเล็บที่ขาดหายไป)

นอกจากนี้ ... โทรศัพท์ที่ไม่ใช่ 4.0 หลายล้านเครื่องจะไม่ทำงานกับรหัสนั้นเลย



0

คล้ายกับ @Guillaume ฉันได้สร้างคลาสย่อยของ UIButton เป็น Swift-File จากนั้นตั้งค่าคลาสที่กำหนดเองของฉันใน Interface Builder:

ตัวสร้างอินเทอร์เฟซ.

และนี่คือไฟล์ Swift:

import UIKit

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

-1

ฉันมีปัญหาเดียวกัน แต่ไม่สามารถใช้งานได้ (อาจเป็นข้อบกพร่องของ SDK)

ในที่สุดเพื่อเป็นการแก้ปัญหาชั่วคราวUIImageViewฉันวางปุ่มด้านหลังและตั้งค่าตัวเลือกที่ต้องการจากนั้นก็วางช่องว่างUIButtonไว้ด้านบน


7
ที่นี่มีเสียงสะท้อนไหม ;-)
Dan Ray
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.