Apakah mungkin untuk mengubah warna latar belakang UIButtons?

105

Yang ini membuatku bingung.

Apakah mungkin untuk mengubah warna latar belakang UIButton di Cocoa untuk iPhone. Saya sudah mencoba mengatur warna latar belakang tetapi hanya mengubah sudutnya. setBackgroundColor:tampaknya menjadi satu-satunya metode yang tersedia untuk hal-hal seperti itu.

[random setBackgroundColor:[UIColor blueColor]];
[random.titleLabel setBackgroundColor:[UIColor blueColor]];
dubbeat
sumber
bisakah kamu memperbaiki gambar, atau menghapusnya? kthx;)
stigi
o-0 hmmmm ....., gambarnya bagus tapi sekarang tidak muncul lagi. Baru saja menghapusnya
dubbeat
Ini adalah duplikat stackoverflow.com/questions/372731/…
Brad Larson
Saya memecahkan masalah ini di posting saya sebelumnya, silakan periksa tautan [Ubah secara dinamis batas atau garis belakang UIButton] [1] [1]: stackoverflow.com/questions/9733213/…
IMMORTAL
tutorial yang baik dan kode contoh ditemukan di sini cimgf.com/2010/01/28/…
Shamsudheen TK

Jawaban:

160

Ini dapat dilakukan secara terprogram dengan membuat replika:

loginButton = [UIButton buttonWithType:UIButtonTypeCustom];
[loginButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
loginButton.backgroundColor = [UIColor whiteColor];
loginButton.layer.borderColor = [UIColor blackColor].CGColor;
loginButton.layer.borderWidth = 0.5f;
loginButton.layer.cornerRadius = 10.0f;

edit: tentu saja, Anda harus #import <QuartzCore/QuartzCore.h>

edit: untuk semua pembaca baru, Anda juga harus mempertimbangkan beberapa opsi yang ditambahkan sebagai "kemungkinan lain". untuk pertimbangan Anda.

Karena ini adalah jawaban lama, saya sangat menyarankan membaca komentar untuk pemecahan masalah

Stian Storrvik
sumber
Inilah yang dicari OP.
Steven
4
manis! Dari semua soln yang saya temukan, ini yang saya gunakan. Sebagai poin klarifikasi, membuat 'replika' berarti menggunakan Quartz untuk menggambar persegi panjang bersudut di tombol kustom, daripada menggunakan tombol jenis RoundedRect. Pada awalnya saya pikir itu berarti membuat duplikat persegi bundar dengan warna berbeda untuk mensimulasikan perubahan warna bg.
daver
1
Bekerja dengan sempurna, jawaban terbaik untuk OP. Terima kasih telah berbagi.
Bram
@daver: Jawaban ini sangat populer sehingga pasti ada kelebihan yang saya lewatkan. Bagaimana cara mengubah warna latar belakang menurut negara? Agaknya seseorang harus secara eksplisit mengubah warna latar belakang setiap kali status berubah. Tombol saya dinonaktifkan saat ditekan hingga layanan web merespons. Haruskah saya mengubah warna sorotan saat ditekan dan mengubah pengatur waktu ke warna nonaktif sambil menunggu ws merespons? Jika saya melewatkan intinya, bisakah seseorang menjelaskan. Terima kasih Polly.
Polly
1
@Polly: Maaf tidak melihat komentar Anda lebih awal, tetapi jika Anda masih tertarik, inilah yang akhirnya saya lakukan: subclass UIButton dan timpa drawRect: menggambar persegi bulat menggunakan beberapa UIBezierPaths. Setelah menggambar, isi dengan gradien menggunakan CGGradientCreateWithColorComponents (). Salah satu argumen untuk fungsi ini adalah larik 4 elemen float (sesuai dengan R, G, B, & alpha). Saya menentukan 2 larik warna, satu untuk setiap status, dan memilih yang sesuai di drawRect berdasarkan status tombol.
daver
59

Saya memiliki pendekatan yang berbeda,

[btFind setTitle:NSLocalizedString(@"Find", @"") forState:UIControlStateNormal];    
[btFind setBackgroundImage:[CommonUIUtility imageFromColor:[UIColor cyanColor]] 
        forState:UIControlStateNormal];
btFind.layer.cornerRadius = 8.0;
btFind.layer.masksToBounds = YES;
btFind.layer.borderColor = [UIColor lightGrayColor].CGColor;
btFind.layer.borderWidth = 1;

Dari CommonUIUtility,

+ (UIImage *) imageFromColor:(UIColor *)color {
    CGRect rect = CGRectMake(0, 0, 1, 1);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    //  [[UIColor colorWithRed:222./255 green:227./255 blue: 229./255 alpha:1] CGColor]) ;
    CGContextFillRect(context, rect);
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
}

Jangan lupa #import <QuartzCore/QuartzCore.h>

karim
sumber
2
Bagus. Saya menemukan saya harus menambahkanbtFind.layer.borderWidth = 1;
DefenestrationDay
Saya suka solusi ini, tetapi saat ini saya tidak dapat menggunakannya. Saya mendapatkan kesalahan, karena "CommonUIUtility" tidak dapat ditemukan. Google baru saja memberi saya barang-barang gerhana, tapi saya rasa itu harus ada di QuartzCore? Ada ide?
Stephan
Tidak, itu adalah kelas yang ditentukan pengguna untuk melakukan hal-hal umum UI di aplikasi. Anda menulis metode imageFromColor di kelas Anda sendiri.
karim
1
Bau seperti metode kategori pada UIButton: setBackgroundColor:(UIColor *) forState:(UIControlState).
EthanB
3
Sangat konyol bahwa kami menggunakan iOS 7 dan ini MASIH cara terbersih untuk menambahkan warna latar belakang
dmur
32

Saya berasumsi Anda sedang berbicara tentang UIButton dengan UIButtonTypeRoundedRect? Anda tidak dapat mengubah warna latar belakangnya. Ketika Anda mencoba mengubah warna latar belakangnya, Anda lebih suka mengubah warna persegi dengan tombol yang digambar (yang biasanya jelas). Jadi ada dua cara untuk pergi. Entah Anda membuat subkelas UIButton dan menimpa -drawRect:metodenya atau Anda membuat gambar untuk status tombol yang berbeda (yang baik-baik saja untuk dilakukan).

Jika Anda mengatur gambar latar belakang di Interface Builder, Anda harus memperhatikan bahwa IB tidak mendukung pengaturan gambar untuk semua status yang dapat dimiliki tombol, jadi saya sarankan mengatur gambar dalam kode seperti ini:

UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];
[myButton setBackgroundImage:[UIImage imageNamed:@"normal.png"] forState:UIControlStateNormal];
[myButton setBackgroundImage:[UIImage imageNamed:@"disabled.png"] forState:UIControlStateDisabled];
[myButton setBackgroundImage:[UIImage imageNamed:@"selected.png"] forState:UIControlStateSelected];
[myButton setBackgroundImage:[UIImage imageNamed:@"higligted.png"] forState:UIControlStateHighlighted];
[myButton setBackgroundImage:[UIImage imageNamed:@"highlighted+selected.png"] forState:(UIControlStateHighlighted | UIControlStateSelected)];

Baris terakhir menunjukkan cara mengatur gambar untuk status yang dipilih & disorot (itu yang tidak dapat diatur oleh IB). Anda tidak memerlukan gambar yang dipilih (baris 4 & 6) jika tombol Anda tidak memerlukan status yang dipilih.

stigi
sumber
Terima kasih atas penjelasannya. Hanya pertanyaan singkat. Jika saya menimpa metode drawrect, saya rasa itu akan melibatkan saya menggunakan perpustakaan gambar? Sesuatu sendiri garis-garis pemrograman menggambar persegi panjang bulat dan mengisinya dengan warna?
dubbeat
2
Saya baru saja melakukan kueri google singkat untuk "iphone drawrect round corners" dan menemukan ini: iphonedevelopment.blogspot.com/2008/11/… Periksa metode drawrect untuk contoh cara menggambar round rect. Anda dapat menggunakan CGContextSetFillColorWithColordan CGContextFillPathuntuk mengisi jalur yang digambar oleh CGContextAddArcToPoint.
stigi
2
+50 untuk menunjukkan potensi bitmasking untuk status kontrol, yaitu: forState:(UIControlStateHighlighted | UIControlStateSelected)Cheers.
NSTJ
28

Kemungkinan lain:

  1. Buat UIButton di Interface builder.
  2. Beri tipe 'Custom'
  3. Sekarang, di IB dimungkinkan untuk mengubah warna latar belakang

Namun, tombolnya persegi, dan bukan itu yang kami inginkan. Buat IBOutlet dengan referensi ke tombol ini dan tambahkan yang berikut ini ke metode viewDidLoad:

[buttonOutlet.layer setCornerRadius:7.0f];
[buttonOutlet.layer setClipToBounds:YES];

Jangan lupa untuk mengimpor QuartzCore.h

wubbe
sumber
7
Sempurna, terima kasih! Saya tidak yakin apakah itu karena versi iOS yang saya gunakan (5.1) tetapi setClipToBounds tidak tersedia. Sebagai gantinya saya menggunakan buttonOutlet.layer.masksToBounds = TRUE;
iforce2d
Ketika saya menambahkan kode ini, itu menunjukkan persegi bulat, tetapi ketika saya mengkliknya, tombol tidak membalikkan sorotan. Apa yang sedang terjadi?
Akankah
Masalah dengan pendekatan ini adalah Anda tidak dapat menyetel warna latar belakang untuk status tombol yang disorot.
ch3rryc0ke
17

Subclass UIButton dan timpa metode setHighlighted dan setSelected

-(void) setHighlighted:(BOOL)highlighted {

  if(highlighted) {
    self.backgroundColor = [self.mainColor darkerShade];
  } else {
    self.backgroundColor = self.mainColor;
  }
  [super setHighlighted:highlighted];
}

-(void) setSelected:(BOOL)selected {

  if(selected) {
    self.backgroundColor = [self.mainColor darkerShade];
  } else {
    self.backgroundColor = self.mainColor;
  }
  [super setSelected:selected];
}

Metode darkerShade saya berada dalam kategori UIColor seperti ini

-(UIColor*) darkerShade {

  float red, green, blue, alpha;
  [self getRed:&red green:&green blue:&blue alpha:&alpha];

  double multiplier = 0.8f;
  return [UIColor colorWithRed:red * multiplier green:green * multiplier blue:blue*multiplier alpha:alpha];
}
Mugunth
sumber
7

UIButton berwarna

Jika Anda tidak ingin menggunakan gambar, dan ingin terlihat persis seperti gaya Rounded Rect, cobalah ini. Cukup tempatkan UIView di atas UIButton, dengan bingkai identik dan topeng ubah ukuran otomatis, setel alfa ke 0,3, dan setel latar belakang ke warna. Kemudian gunakan cuplikan di bawah untuk memotong tepi yang membulat dari tampilan hamparan berwarna. Selain itu, hapus centang pada kotak 'Interaksi Pengguna Diaktifkan' di IB di UIView untuk memungkinkan peristiwa sentuh mengalir ke tombol UIButton di bawahnya.

Salah satu efek sampingnya adalah teks Anda juga akan diwarnai.

#import <QuartzCore/QuartzCore.h>

colorizeOverlayView.layer.cornerRadius = 10.0f;
colorizeOverlayView.layer.masksToBounds = YES;
Jacob Jennings
sumber
7

Kemungkinan lain (imho terbaik dan terindah):

Buat UISegmentedControl dengan 2 segmen dalam warna latar belakang yang diperlukan di Interface Builder. Setel jenisnya ke 'bar'. Kemudian, ubah menjadi hanya satu segmen. Pembuat antarmuka tidak menerima satu segmen jadi Anda harus melakukannya secara terprogram.

Oleh karena itu, buat IBOutlet untuk tombol ini dan tambahkan ini ke viewDidLoad tampilan Anda:

[segmentedButton removeSegmentAtIndex:1 animated:NO];

Sekarang Anda memiliki tombol berwarna mengkilap yang indah dengan warna latar yang ditentukan. Untuk tindakan, gunakan peristiwa 'nilai berubah'.

(Saya menemukan ini di http://chris-software.com/index.php/2009/05/13/creating-a-nice-glass-buttons/ ). Terima kasih Chris!

wubbe
sumber
5

Saya 99% persen yakin bahwa Anda tidak bisa begitu saja mengubah warna latar belakang UIButton. Sebaliknya Anda harus pergi dan mengubah sendiri gambar latar belakang yang menurut saya menyebalkan. Saya kagum bahwa saya harus melakukan ini.

Jika saya salah atau jika ada cara yang lebih baik tanpa harus mengatur gambar latar belakang tolong beri tahu saya

[random setBackgroundImage:[UIImage imageNamed:@"toggleoff.png"] forState:UIControlStateNormal];
    [random setTitleColor:[UIColor darkTextColor] forState:UIControlStateNormal];


[random setBackgroundImage:[UIImage imageNamed:@"toggleon.png"] forState:UIControlStateNormal];
    [random setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
dubbeat
sumber
5
Anda benar sekali. Ini menyebalkan, dan sesuatu yang harus dilakukan dalam beberapa menit alih-alih repot membuat gambar. Ditambah lagi jika kancingmu bulat, itu membuatnya lebih sulit untuk dilakukan juga ... Sungguh menyakitkan.
Henley Chiu
2

Sesuai saran @EthanB dan @karim membuat persegi panjang yang diisi kembali, saya baru saja membuat kategori untuk UIButton untuk mencapai ini.

Cukup masukkan kode Kategori: https://github.com/zmonteca/UIButton-PLColor

Pemakaian:

[button setBackgroundColor:uiTextColor forState:UIControlStateDisabled];

ForStates opsional untuk digunakan:

UIControlStateNormal
UIControlStateHighlighted
UIControlStateDisabled
UIControlStateSelected
zmonteca.dll
sumber
2

Anda juga dapat menambahkan CALayer ke tombol - Anda dapat melakukan banyak hal dengan ini termasuk overlay warna, contoh ini menggunakan lapisan warna polos Anda juga dapat dengan mudah mengubah warnanya. Berhati-hatilah meskipun lapisan yang ditambahkan mengaburkan lapisan di bawahnya

+(void)makeButtonColored:(UIButton*)button color1:(UIColor*) color
{

    CALayer *layer = button.layer;
    layer.cornerRadius = 8.0f;
    layer.masksToBounds = YES;
    layer.borderWidth = 4.0f;
    layer.opacity = .3;//
    layer.borderColor = [UIColor colorWithWhite:0.4f alpha:0.2f].CGColor;

    CAGradientLayer *colorLayer = [CAGradientLayer layer];
    colorLayer.cornerRadius = 8.0f;
    colorLayer.frame = button.layer.bounds;
    //set gradient colors
    colorLayer.colors = [NSArray arrayWithObjects:
                         (id) color.CGColor,
                         (id) color.CGColor,
                         nil];

    //set gradient locations
    colorLayer.locations = [NSArray arrayWithObjects:
                            [NSNumber numberWithFloat:0.0f],
                            [NSNumber numberWithFloat:1.0f],
                            nil];


    [button.layer addSublayer:colorLayer];

}
gheese
sumber
Cemerlang!!!!!! Tapi tidak bisa dipanggil beberapa kali dengan tombol yang sama. Bisa, tetapi lapisan baru ditambahkan lagi dan lagi.
Valeriy Van
@StanJames: Pengeditan kode harus disarankan oleh komentar (atau, jika sesuai, oleh jawaban Anda sendiri).
mafso
1

tambahkan target kedua untuk UIButtonuntuk UIControlEventToucheddan ubah UIButtonwarna latar belakang. Kemudian ubah kembali ke UIControlEventTouchUpInsidetarget;

Shaun
sumber
1

Untuk tombol yang terlihat profesional dan bagus, Anda dapat memeriksa komponen tombol kustom ini . Anda dapat menggunakannya secara langsung di tampilan dan tampilan tabel Anda atau memodifikasi kode sumber agar sesuai dengan kebutuhan Anda. Semoga ini membantu.

Ahmet Ardal
sumber
1

Ini tidak seanggun sub-classing UIButton, namun jika Anda hanya ingin sesuatu yang cepat - yang saya lakukan adalah membuat tombol kustom, lalu gambar 1px kali 1px dengan warna yang saya inginkan, dan atur latar belakang tombol ke gambar itu untuk status yang disorot - berfungsi untuk kebutuhan saya.

SMSidat
sumber
1

Saya tahu ini sudah lama ditanyakan dan sekarang ada UIButtonTypeSystem baru. Tetapi pertanyaan yang lebih baru ditandai sebagai duplikat dari pertanyaan ini jadi inilah jawaban saya yang lebih baru dalam konteks tombol sistem iOS 7, gunakan .tintColorproperti.

let button = UIButton(type: .System)
button.setTitle("My Button", forState: .Normal)
button.tintColor = .redColor()
DonnaLea
sumber
0

[myButton setBackgroundColor:[UIColor blueColor]]; [myButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];

Mungkin saja mengubah cara ini atau melanjutkan Storyboard dan mengubah latar belakang pada opsi di sisi kanan.

Vinicius Carvalho
sumber
0

Cepat 3:

        static func imageFromColor(color: UIColor, width: CGFloat, height: CGFloat) -> UIImage {
            let rect = CGRect(x: 0, y: 0, width: width, height: height)
            UIGraphicsBeginImageContext(rect.size)
            let context = UIGraphicsGetCurrentContext()!
            context.setFillColor(color.cgColor)
            context.fill(rect)
            let img = UIGraphicsGetImageFromCurrentImageContext()!
            UIGraphicsEndImageContext()
            return img
        }

        let button = UIButton(type: .system)
        let image = imageFromColor(color: .red, width: 
        button.frame.size.width, height: button.frame.size.height)
        button.setBackgroundImage(image, for: .normal)
pawurb
sumber
Ini akan menjadi jawaban yang jauh lebih berguna jika Anda mengatakan bagaimana memanggil atau menggunakan kode yang Anda masukkan di sana. Apakah itu masuk ke ekstensi UIButton?
Michael Dautermann