UIButton tidak akan masuk ke Aspect Fit di iPhone

105

Saya punya beberapa UIButtons, dan di IB mereka disetel ke Aspect Fit, tapi untuk beberapa alasan mereka selalu meregang. Apakah ada hal lain yang harus Anda atur? Saya mencoba semua mode tampilan yang berbeda dan tidak ada yang berfungsi, semuanya meregang.

marty
sumber
Jawaban @Werner Altesischer benar. Lakukan perubahan yang sesuai.
Harshit Gupta
1
@marty Apakah Anda menyetel gambar latar belakang atau gambar? gambar latar belakang tidak mendukungnya, hanya gambar.
Juan Boero

Jawaban:

45

Saya pernah mengalami masalah itu sebelumnya. Saya menyelesaikannya dengan meletakkan gambar saya di UIImageView, di mana contentModepengaturan benar-benar berfungsi, dan meletakkan kustom transparan UIButtondi atasnya.

EDIT: Jawaban ini sudah usang. Lihat jawaban @Werner Altewischer untuk jawaban yang benar di iOS versi modern.

Dan Ray
sumber
Ya sudah mencobanya, tapi sekarang tidak bisa mendapatkan tombol untuk mereparasi ke gambar
marty
Bagaimana Anda mengelola status tombol dengan teknik ini? Sepertinya menanggapi interaksi pengguna seperti "disorot" akan menjadi mimpi buruk.
SooDesuNe
3
Ini mungkin cara yang tepat untuk melakukan ini 2,5 tahun yang lalu ketika pertanyaan ini dijawab, tetapi sekarang Anda dapat mengedit ImageView internal UIButton dan mengatur mode konten di sana. Lihat jawabannya oleh @Werner Altewischer
Steve Haley
233

Solusinya adalah untuk mengatur contentModepada imageViewmilik UIButton. The UIButtonharus dibuat dengan jenis kustom untuk bekerja saya percaya (jika tidak nildikembalikan untuk properti ini).

Werner Altewischer
sumber
67
Ini berhasil untuk saya:[button.imageView setContentMode:UIViewContentModeScaleAspectFit];
ayreguitar
2
Ini juga berfungsi untuk saya, tetapi jika saya menyetel adjustsImageWhenHighlighted = YES, gambar akan melebar lagi saat saya mengetuk tombol.
cduck
1
Peregangan pada AdjustsImage telah dihilangkan di iOS 6.
Ben Flynn
3
Di iOS 8, ini sebenarnya tidak berhasil untuk saya. Jawaban asli (dengan menempatkan imageView di belakang tombol transparan) berfungsi paling baik.
pengguna1416564
3
dalam Swift du jour:button.imageView!.contentMode = UIViewContentMode.scaleAspectFit
Nestor
57

Metode ini berhasil untuk saya dengan sangat baik .:

Di Xib pilih tombol dan atur user defined runtime attributes:

  • Jalur kunci: self.imageView.contentMode
  • Tipe: Number
  • Nilai: 1

Klik di sini untuk melihat lebih jelas solusinya

Kami menggunakan nomor karena Anda tidak dapat menggunakan enum di sana. Tetapi UIViewContentModeScaleAspectFit sama dengan 1.

István Stefánovics
sumber
2
Ini juga memperbarui gambar di pembuat antarmuka selama waktu desain. Solusi bagus.
George Filippakos
Solusi hebat, sedikit kode dan berfungsi seperti pesona, enum didasarkan pada item daftar mode konten.
Kross
Anda juga dapat menambahkan ekstensi untuk membuatnya lebih mudah: extension UIButton { @IBInspectable var imageContentMode: Int { get {return imageView?.contentMode.rawValue ?? 0} set {imageView?.contentMode = UIViewContentMode(rawValue: newValue) ?? .scaleAspectFit} } }
Yonat
Tanpa 'diri' imageView.contentModeberhasil untuk saya!
byJeevan
22

Jika Anda melakukan ini di Interface Builder, Anda dapat menggunakan inspektur atribut Runtime untuk menyetelnya secara langsung tanpa kode apa pun.

Setel Jalur Kunci Anda pada tombol menjadi "imageView.contentMode" dengan jenis "Angka" dan nilai "1" (atau mode mana pun yang Anda inginkan).

imageview.contentMode = 1

averydev
sumber
14

Gunakan imageView tombol untuk contentMode. Tidak langsung pada tombol itu sendiri.

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

Jika Anda meletakkan gambar di UIImageViewbelakang tombol, Anda akan kehilangan fungsionalitas built-in dari UIButtonkelas, seperti adjustsImageWhenHighlighteddan adjustsImageWhenDisabled, dan tentu saja kemampuan untuk mengatur gambar yang berbeda untuk keadaan yang berbeda (tanpa repot melakukan ini sendiri).

Jika kita ingin gambar tidak terikat untuk semua status kontrol , salah satu pendekatannya adalah menggunakan gambar imageWithCGImage:scale:orientation, seperti dalam metode berikut:

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

Untuk menerapkan ini kami akan menulis:

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

Ini akan mencegah gambar meregang di semua status kontrol. Ini berhasil untuk saya, tetapi beri tahu saya jika tidak!

CATATAN: Di sini kami menangani masalah yang berkaitan dengan UIButton, tetapi insideButton:mungkin juga insideView:, atau apa pun yang ingin disesuaikan dengan gambar.

Alexander Wallin
sumber
6

Saya mengalami masalah ini beberapa waktu lalu. Masalah yang saya alami adalah saya mencoba menerapkan efek ini ke latar belakang UIButton yang terbatas dan karena itu berarti Anda tidak dapat menyesuaikannya semudah itu.

Triknya adalah mengaturnya hanya sebagai gambar kemudian menerapkan teknik @ ayreguitar dan itu harus memperbaikinya!

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

Ini berhasil untuk saya

[button.imageView setContentMode:UIViewContentModeScaleAspectFit];

Terima kasih kepada @ayreguitar atas komentarnya

Karan Alangat
sumber
4

Berikut jawaban alternatif dengan cepat:

myButton.imageView?.contentMode = .ScaleAspectFit
João Neves
sumber
4

Menggabungkan beberapa jawaban berbeda menjadi satu solusi-- buat tombol dengan tipe kustom, setel properti imageView contentMode tombol, dan setel gambar untuk tombol (bukan gambar latar belakang, yang masih akan diskalakan untuk diisi).

//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)
Penipu
sumber
3
btn.imageView.contentMode = UIViewContentModeScaleAspectFit;
selaband
sumber
Meskipun cuplikan kode ini dapat menyelesaikan pertanyaan, menyertakan penjelasan sangat membantu meningkatkan kualitas posting Anda. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa mendatang, dan orang-orang itu mungkin tidak tahu alasan saran kode Anda. - Dari ulasan
Ferrybig
2

Jawaban ini berdasarkan jawaban @ WernerAltewischer .

Untuk menghindari menghubungkan tombol saya ke IBOutlet untuk mengeksekusi kode di atasnya, saya membuat subclass kelas UIButton:

// .h
@interface UIButtonWithImageAspectFit : UIButton
@end

// .m
@implementation UIButtonWithImageAspectFit

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

@end



Sekarang buat tombol khusus di xib Anda, dan atur gambarnya (bukan gambar latar belakang):

UIButtonWithImageAspectFit: membuat dan mengatur gambar


Kemudian, setel kelasnya:

UIButtonWithImageAspectFit: setel kelas khusus

Kamu sudah selesai!
Alih-alih
UIButton tanpa kesesuaian aspek gambar
kesesuaian aspek gambar tombol Anda sekarang seperti yang diharapkan:
UIButton dengan aspek kesesuaian gambar

Guillaume
sumber
2

ios 12. Anda perlu menambahkan juga Alignment konten

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()


    }

}
João Nunes
sumber
1

Saya memiliki masalah dengan gambar yang tidak mengubah ukuran secara proporsional sehingga cara saya memperbaikinya menggunakan sisipan tepi.

fooButton.contentEdgeInsets = UIEdgeInsetsMake(10, 15, 10, 15);
ninjaneer
sumber
1

Mode konten UIView berlaku untuk "konten" CALayer yang sesuai. Ini berfungsi untuk UIImageViews karena mereka mengatur CALayerkonten ke yang sesuai CGImage.

drawRect: akhirnya merender ke konten lapisan.

Sebuah custom UIButton(sejauh yang saya tahu) tidak memiliki konten (tombol gaya rounded-rect mungkin dirender menggunakan konten). Tombol tersebut memiliki subview: latar belakang UIImageView, gambar UIImageView, dan judul UILabel. Mengatur contentModepada subview dapat melakukan apa yang Anda inginkan, tetapi mengotak-atik UIButtonhierarki tampilan agak tidak-tidak.

tc.
sumber
1

Perubahan UIButton.imageView.contentModetidak berhasil untuk saya.
Saya memecahkan masalah dengan mengatur gambar ke properti 'Background'.
Anda dapat menambahkan batasan rasio jika perlu

Taman Soohwan
sumber
1

Ini tumpang tindih dengan banyak jawaban lainnya, tetapi solusi bagi saya adalah melakukannya

  • mengatur contentModedari UIImageViewuntuk tombol untuk .ScaleAspectFit- yang baik dapat dilakukan dalam “Ditetapkan Pengguna Runtime Atribut” di Interface Builder (yaitu. self.imageView.contentMode, Nomor, 1) atau dalam UIButtonsubclass;
  • nonaktifkan "Autoresize Subviews";
  • setel "Edge" ke "Image" dan nilai "Top" dan "Bottom" yang sesuai untuk "Inset" (yang mungkin hanya diperlukan jika Anda, seperti saya, menggunakan PDF sebagai gambar).
plindberg
sumber
0

Anda dapat menggunakan imageWithCGImage seperti yang ditunjukkan di atas (tetapi tanpa tanda kurung yang hilang).

Juga ... jutaan ponsel non-4.0 tidak akan berfungsi dengan kode itu sama sekali.

Alice
sumber
0

[button sizeToFit] bekerja untuk saya.

Hila
sumber
0

Mirip dengan @Guillaume, saya telah membuat subclass UIButton sebagai Swift-File. Kemudian setel kelas kustom saya di Interface Builder:

pembuat antarmuka.

Dan di sini file Swiftnya:

import UIKit

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

Saya memiliki masalah yang sama, tetapi saya tidak bisa membuatnya berfungsi (mungkin itu bug dengan SDK).

Akhirnya, sebagai solusinya, saya meletakkan di UIImageViewbelakang tombol saya dan mengatur opsi yang saya inginkan, lalu hanya menempatkan kosong UIButtondi atasnya.

Anshu Chimala
sumber
7
Apakah ada gaung di sini? ;-)
Dan Ray