UIButton tidak mendengarkan pengaturan mode konten?


92

firstButton adalah UIButton bertipe Custom. Saya secara terprogram menempatkan tiga di antaranya di setiap sel tabel, dengan demikian:

[firstButton setImage:markImage forState:UIControlStateNormal];
[firstButton setContentMode:UIViewContentModeScaleAspectFit];
[cell.contentView addSubview:firstButton];

Di tempat lain, saya mengatakannya ke clipToBounds. Apa yang saya dapatkan adalah potongan dari kotak tengah gambar, bukan rendering berskala aspek. Saya telah mencoba banyak cara ini, termasuk mengatur properti mode di firstButton.imageView, yang juga sepertinya tidak berfungsi.


1
Lihat solusi oleh Chris Nolet di bawah ini: button.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
Matt

Lihat stackoverflow.com/a/28205566/481207 yang menunjukkan bahwa pengaturan contentVerticalAlignment dan contentHorizontalAlignment diperlukan untuk UIViewContentModeScaleAspectFit.
Matt

Jawaban:


187

Saya memiliki masalah yang sama. Saya melihat pertanyaan ini agak kuno, tetapi saya ingin memberikan jawaban yang jelas dan benar untuk menyelamatkan orang lain (seperti saya) beberapa saat ketika muncul di hasil pencarian mereka.

Saya butuh sedikit mencari dan bereksperimen, tetapi saya menemukan solusinya. Cukup setel ContentMode dari ImageView "tersembunyi" yang ada di dalam UIButton.

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

Mungkin itulah yang disinggung Dan Ray dalam jawaban yang diterima, tapi saya kira tidak.


1
Tidak, tidak. Solusi yang saya putuskan adalah menggunakan UIImageView untuk menyimpan gambar, lalu UIButton transparan dan transparan jenis "custom" di atasnya.
Dan Ray

Dave, setidaknya di iOS 3.2, solusi Anda tampaknya tidak berhasil untuk saya. Sayang sekali, karena saya berharap mendapatkan sorotan gambar di klik "gratis". Saya bahkan memastikan bahwa button.imageView tidak nihil di mana saya mengatur contentMode, dan mengatur gambar setelah mengatur contentMode, seperti yang Anda lakukan.
Jacques

2
Hanya untuk memperjelas, "tidak berfungsi" berarti "gambar ditampilkan dengan resolusi penuh, tidak diperkecil seperti yang saya harapkan".
Jacques

Jacques, di atas berfungsi untuk saya di iOS 4.x. Sayangnya, saya dapat mereproduksi masalah "tidak akan mengubah ukuran" saat membuat dengan target v3.2. Saya mencoba mengubah ukuran bingkai tampilan UIButton, tetapi tampaknya itu juga tidak membantu. ugh.
Dave

4
Lihat solusi oleh Chris Nolet di bawah ini: button.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
Matt

74

Jika Anda berurusan dengan gambar UIButton (bukan backgroundImage), menyetel contentMode pada UIButton itu sendiri atau pada imageView-nya tidak berpengaruh (terlepas dari jawaban lain yang mengatakan).

Atau lakukan ini sebagai gantinya:

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

Atau ukuran gambar Anda sesuai.

ATAU cukup gunakan UIImageView (yang sesuai dengan contentMode) dengan UITapGestureRecognizer terpasang padanya, atau UIButton transparan di atasnya.


4
Ini berfungsi untuk kasus saya di iOS 7 sedangkan yang lain di sini tidak.
Byte

5
Mengatur contentHorizontalAlignment dan contentVerticalAlignment adalah solusi yang tepat. Lihat stackoverflow.com/a/28205566/481207 untuk penjelasannya.
Matt

1
Ini jawaban yang saya cari.
ninjaneer

4
Jawaban ini salah. Anda tidak perlu set contentModepada imageViewjika Anda ingin melakukan apapun aspek mengisi atau fit, seperti jawaban lainnya telah diklarifikasi. Lihat: stackoverflow.com/a/7944316/746890 .
Chris Nolet

52

Daripada mengatur contentModetombol itu sendiri, Anda akan ingin mengatur contentHorizontalAlignmentdan contentVerticalAlignmentproperti dan (yang terpenting) contentModeuntuk tombol itu imageViewuntuk segala jenis aspek isian atau kecocokan. Berikut contohnya:

button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
button.imageView.contentMode = UIViewContentModeScaleAspectFit;

Tentu saja, Anda juga dapat melakukan hal lain seperti menyelaraskan gambar tombol ke bagian atas tombol. Jika Anda tidak memerlukan aspek isian atau kecocokan, Anda dapat mengatur perataannya sendiri:

button.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;

Di Swift, Anda ingin menggunakan:

button.contentHorizontalAlignment = .fill
button.contentVerticalAlignment = .fill
button.imageView?.contentMode = .scaleAspectFit

Ini berfungsi untuk semua versi iOS, termasuk versi terbaru dengan tata letak otomatis, (yaitu iOS 4 hingga iOS 11+).


2
Terima kasih Chris - itu menyelesaikan masalah saya, atau lebih tepatnya, itu terjadi dalam kombinasi dengan contentEdgeInsets, untuk sedikit memundurkan gambar saya dari tepi atas.
Rob Reuss

7

Setelah beberapa jam kebingungan, berikut cara saya membuatnya berfungsi di iOS 3.2. Seperti yang disebutkan senja, menggunakan setBackgroundImage daripada setImage melakukan pekerjaan itu untuk saya.

CGRect myButtonFrame = CGRectMake(0, 0, 250, 250);
UIImage *myButtonImage = [UIImage imageNamed:@"buttonImage"];

UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];

[myButton setBackgroundImage:myButtonImage forState:UIControlStateNormal];
[myButton setFrame: myButtonFrame];
[myButton setContentMode: UIViewContentModeScaleAspectFit];

6

Jawabannya adalah menggunakan UIImageView dengan semua pengaturan Mode Konten yang Anda inginkan, dan kemudian melapisi tombol kustom di atasnya. Bodoh bahwa Anda tidak dapat melakukan itu semua dalam satu kesempatan, tetapi tampaknya Anda tidak dapat melakukannya.


4

Menemukan perbaikan untuk ini. Setel adjustsImageWhenHighlightedproperti UIButtonmenjadi NO.

  UIButton *b = [[UIButton alloc] initWithFrame:rect];
        [b setImage:image forState:UIControlStateNormal];
        [b.imageView setContentMode:UIViewContentModeScaleAspectFill];
        [b setAdjustsImageWhenHighlighted:NO];

Semoga ini membantu. Jangan ragu untuk berkomentar di bawah ini, saya akan menindaklanjuti setiap pertanyaan yang Anda miliki.


Ini adalah solusi yang tepat.
Gaurav

Tidak berhasil. Ini hanya mencegah tombol untuk menyorot.
Matt

4

Jawaban saya mirip dengan Kuba. Saya perlu gambar saya disetel secara terprogram.

UIImage *image = [[UIImage alloc] initWithContentsOfFile:...];
[button setBackgroundImage:image forState:UIControlStateNormal];
button.imageView.contentMode = UIViewContentModeScaleAspectFill; //this is needed for some reason, won't work without it.
for(UIView *view in button.subviews) {
    view.contentMode = UIViewContentModeScaleAspectFill;
}

3

Satu-satunya solusi yang berhasil untuk saya:

[button setImage:image forState:UIControlStateNormal];
button.imageView.contentMode = UIViewContentModeScaleAspectFill;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;


1

Sebagai ganti setImage, coba setBackgroundImage


3
Hmp. A, itu bodoh, itu harus menghormati pengaturan MODE KONTEN untuk KONTENnya, bukan? Dan B, itu MASIH tidak menghormati pengaturan mode - sekarang terkunci ke "stretch" (yang, dalam hal ini, lebih seperti "squeeze"), dan tidak menskalakan konten sehubungan dengan aspeknya perbandingan.
Dan Ray

1

Saya yakin kami memiliki masalah pembuat antarmuka sederhana di sini - tampaknya IB mengabaikan perubahan mode konten SETELAH Anda menyetel properti gambar.

solusinya sesederhana itu: atur mode konten, hapus nama-gambar yang telah ditetapkan sebelumnya (pastikan Anda menghapusnya di semua status, default, disorot, dll.), lalu masukkan kembali nama-gambar yang diinginkan di semua status yang diinginkan - et voilĂ  .


1
Hal yang sama berlaku untuk mengatur mode konten secara terprogram - jangan atur gambar SEBELUM mengatur mode konten
JohnPayne

0

Saya juga menyarankan untuk melihat adjustsImageWhenHighlighted UIButtonproperti untuk menghindari deformasi aneh pada gambar, saat tombol ditekan.


0

Dalam mencoba untuk mencari tahu ini, metode saya menjadi sedikit hackier seiring berjalannya waktu, dan saya akhirnya subclass UIButton dan overriding setHighlighted:

Bagi saya, ini berfungsi dengan hanya merobohkan gambar alpha menjadi 0,5, karena mereka berada di latar belakang hitam.

Namun, ini hanya berfungsi jika saya mengomentari [super setHighlighted:] (di mana tampaknya kode melar gambar sedang berlangsung), yang rasanya tidak seperti cara yang tepat untuk menyelesaikan ini sama sekali ... semuanya tampak seperti bekerja dengan baik. Kita akan lihat bagaimana hal itu bertahan saat saya terus mengerjakannya.

- (void)setHighlighted:(BOOL)highlight {
    if (highlight) {
        [self.imageView setAlpha:.5];
    }  else {
        [self.imageView setAlpha:1];        
    }

//    [super setHighlighted:highlight];
}

1
Jika ada yang menganggap ini relevan, metode saya di atas tampaknya berfungsi dengan baik sampai saya meletakkan tombol pada UIScrollView, di mana terkadang sorotan tombol "macet", yang saya duga mungkin akhirnya terjadi.
jankins

0

Jika ada yang mencari jawaban yang berfungsi di iOS 6 dan iOS 7 dan storyboard:

Anda dapat mengatur gambar di papan cerita Anda:

masukkan deskripsi gambar di sini

Lalu:

for(UIView* testId in self.subviews) {
    if([testId isKindOfClass:[UIImageView class]])
        [testId setContentMode:UIViewContentModeScaleAspectFill];
}

0

Jika UIButton tampaknya tidak mendengarkan pengaturan batasan tata letak, periksa apakah gambar lebih besar dari ukuran tombol. Selalu gunakan gambar @ 2x dan @ 3x untuk resolusi retina.


0

Kedua hal ini (yang awalnya cukup sulit ditemukan) akan meregangkan gambar UIButton Anda agar sesuai dengan ukuran tombol:

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

seseorang harus selalu mencoba untuk mengaturnya di Storyboard daripada kode.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.