Bir UIButtons arka plan rengini değiştirmek mümkün müdür?


105

Bu beni zor durumda bıraktı.

İPhone için Cocoa'da bir UIButton'un arka plan rengini değiştirmek mümkün mü? Arka plan rengini ayarlamayı denedim ama sadece köşeleri değiştiriyor. setBackgroundColor:bu tür şeyler için mevcut tek yöntem gibi görünüyor.

[random setBackgroundColor:[UIColor blueColor]];
[random.titleLabel setBackgroundColor:[UIColor blueColor]];

resmi düzeltebilir misin yoksa kaldırabilir misin?
kthx

o-0 hmmmm ....., görüntü iyiydi ama artık görünmeyecek. Yeni silindi
dubbeat


Bu sorunu önceki gönderimde çözüyorum, lütfen [Bir UIButtonunun sınırını veya arka planını dinamik olarak değiştir] [1] [1] bağlantısını kontrol edin: stackoverflow.com/questions/9733213/…
IMMORTAL

iyi öğretici ve örnek kod burada bulunur cimgf.com/2010/01/28/…
Shamsudheen TK

Yanıtlar:


160

Bu, bir kopya oluşturarak programlı olarak yapılabilir:

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;

düzenleme: tabii ki yapmanız gerekecek #import <QuartzCore/QuartzCore.h>

düzenleme: tüm yeni okuyucular için, "başka bir olasılık" olarak eklenen birkaç seçeneği de dikkate almalısınız. senin düşüncen için.

Bu eski bir cevap olduğundan, sorun giderme için yorumları okumanızı şiddetle tavsiye ederim


OP'nin aradığı şey bu.
Steven

4
tatlı! Bulduğum tüm çözümler arasında bu benim birlikte gittiğim çözüm. Açıklığa kavuşturmak gerekirse, bir 'replika' yapmak, RoundedRect tipi bir düğme kullanmak yerine Quartz'ın özel bir düğmede yuvarlak bir dikdörtgen çizmek için kullanılması anlamına gelir. İlk başta, bg rengini değiştirmeyi simüle etmek için bir şekilde yuvarlatılmış bir rektin farklı bir renkle kopyasını yapmak anlamına geldiğini düşündüm.
daver

1
Mükemmel çalıştı, OP'ye en iyi cevap. Paylaşım için teşekkürler.
Bram

@daver: Bu cevap o kadar popüler ki, eksik olduğum için haklı olmalı. Duruma göre arka plan rengi nasıl değiştirilir? Muhtemelen, durum her değiştiğinde arka plan renginin açıkça değiştirilmesi gerekir. Düğmem, bir web hizmeti yanıt verene kadar basıldığında devre dışı bırakıldı. Baskıda rengi vurgulamak için değiştirmeli ve ws'nin yanıt vermesini beklerken zamanlayıcının devre dışı renge geçmesi gerekir mi? Bir noktayı kaçırıyorsam, lütfen birisi açıklayabilir. Teşekkürler Polly.
Polly

1
@Polly: Maalesef yorumunuzu daha önce görmedim, ancak yine de ilgileniyorsanız işte sonunda şunu yaptım: UIButton alt sınıfı ve bazı UIBezierPath'leri kullanarak yuvarlatılmış dikdörtgen çizmek için drawRect'i geçersiz kılın. Çizdikten sonra, CGGradientCreateWithColorComponents () kullanarak bir degrade ile doldurun. Bu fonksiyonun argümanlarından biri 4 elemanlı bir float dizisidir (R, G, B ve alpha'ya karşılık gelir). Her durum için bir tane olmak üzere 2 renk dizisi tanımladım ve düğme durumuna göre drawRect'te uygun olanı seçtim.
daver

59

Benim farklı bir yaklaşımım var

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

CommonUIUtility'den,

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

Unutma #import <QuartzCore/QuartzCore.h>


2
Güzel bir. btFind.layer.borderWidth = 1;
Eklemem

Bu çözümü beğendim ama şu anda kullanamıyorum. Bir hata alıyorum çünkü "CommonUIUtility" bulunamıyor. Google sadece bana tutulma şeyleri veriyor, ancak sanırım QuartzCore'da olmalı? Herhangi bir fikir?
Stephan

Hayır, bu, uygulamada ortak kullanıcı arayüzü işleri yapmak için kullanıcı tanımlı bir sınıftır. İmageFromColor yöntemini kendi sınıfınıza yazarsınız.
karim

1
UIButton bir kategori yöntemiyle gibi kokuyor: setBackgroundColor:(UIColor *) forState:(UIControlState).
EthanB

3
O kadar aptalca ki iOS 7 kullanıyoruz ve bu HALA arka plan rengi eklemenin en temiz yolu
dmur

32

Sanırım bir UIButton'dan bahsediyorsunuz UIButtonTypeRoundedRect? Bunun arka plan rengini değiştiremezsiniz. Arka plan rengini değiştirmeyi denediğinizde, düğmenin üzerine çizildiği rektin rengini değiştirmiş olursunuz (ki bu genellikle açıktır). Yani gitmenin iki yolu var. Ya UIButton'ı alt sınıflarsınız ve -drawRect:yönteminin üzerine yazarsınız ya da farklı düğme durumları için görüntüler yaratırsınız (ki bu tamamen iyidir).

Arayüz Oluşturucu'da arka plan resimlerini ayarlarsanız, IB'nin düğmenin sahip olabileceği tüm durumlar için resim ayarlamayı desteklemediğini fark etmelisiniz, bu nedenle resimleri şu şekilde kodlamanızı öneririz:

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)];

Son satır, seçilen ve vurgulanan durum için bir görüntünün nasıl ayarlanacağını gösterir (IB'nin ayarlayamayacağı tek şey budur). Düğmenin seçili bir duruma ihtiyacı yoksa, seçilen görüntülere (satır 4 ve 6) ihtiyacınız yoktur.


Açıklama için teşekkürler. Sadece hızlı bir soru. Doğru yöntemin üzerine yazarsam, bu bir çizim kitaplığı kullanmamı gerektirecek mi? Programlı olarak yuvarlak bir dikdörtgen çizme ve onu bir renkle doldurma çizgileri tek başına bir şey mi?
dubbeat

2
"İphone yuvarlak köşeleri çiz " için kısa bir google sorgusu yaptım ve şunu buldum: iphonedevelopment.blogspot.com/2008/11/… Yuvarlak bir dikdörtgen çizmenin bir örneği için doğru yöntemi kontrol edin. CGContextSetFillColorWithColorVe CGContextFillPathile çizilen yolu doldurmak için kullanabilirsiniz CGContextAddArcToPoint.
stigi

2
+50, kontrol durumları için bit maskesi oluşturma potansiyeline işaret etmek için, yani: forState:(UIControlStateHighlighted | UIControlStateSelected)Şerefe.
NSTJ

28

Bir başka olasılık:

  1. Arabirim oluşturucuda bir UIB düğmesi oluşturun.
  2. Bir tür 'Özel' verin
  3. Şimdi, IB'de arka plan rengini değiştirmek mümkündür

Ancak düğme kare ve istediğimiz bu değil. Bu düğmeye referansla bir IBOutlet oluşturun ve aşağıdakileri viewDidLoad yöntemine ekleyin:

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

QuartzCore.h dosyasını içe aktarmayı unutmayın


7
Mükemmel, teşekkürler! Kullandığım iOS sürümü (5.1) yüzünden mi emin değilim ama setClipToBounds mevcut değildi. Bunun yerine buttonOutlet.layer.masksToBounds = TRUE;
iforce2d

Bu kodu eklediğimde yuvarlatılmış bir dikdörtgen gösteriyor, ancak üzerine tıkladığımda düğme vurguyu tersine çevirmiyor. Ne oluyor?
Will

Bu yaklaşımla ilgili sorun, düğmenin vurgulanmış durumu için bir arka plan rengi ayarlayamamanızdır.
ch3rryc0ke

17

Alt sınıf UIButton ve geçersiz kılma setHighlighted ve setSelected yöntemleri

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

DarkerShade yöntemim bunun gibi bir UIColor kategorisinde

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

7

renkli UIButton

Görüntüleri kullanmak istemiyorsanız ve tam olarak Rounded Rect stili gibi görünmesini istiyorsanız, bunu deneyin. Aynı çerçeve ve otomatik yeniden boyutlandırma maskesiyle UIB düğmesinin üzerine bir UIView yerleştirin, alfa'yı 0,3'e ayarlayın ve arka planı bir renge ayarlayın. Ardından, renkli kaplama görünümünden yuvarlatılmış kenarları kırpmak için aşağıdaki parçacığı kullanın. Ayrıca, dokunma olaylarının alttaki UIB düğmesine kademeli olarak aktarılmasına izin vermek için UIView'de IB'deki "Kullanıcı Etkileşimi Etkin" onay kutusunun işaretini kaldırın.

Bir yan etki, metninizin de renklendirilmesidir.

#import <QuartzCore/QuartzCore.h>

colorizeOverlayView.layer.cornerRadius = 10.0f;
colorizeOverlayView.layer.masksToBounds = YES;

7

Başka bir olasılık (en iyi ve en güzel imho):

Interface Builder'da gerekli arka plan renginde 2 segmentli bir UISegmentedControl oluşturun. Türü 'bar' olarak ayarlayın. Ardından, yalnızca bir segmente sahip olacak şekilde değiştirin. Arabirim oluşturucu bir segmenti kabul etmediğinden, bunu programlı olarak yapmanız gerekir.

Bu nedenle, bu düğme için bir IBOutlet oluşturun ve bunu görünümünüzün viewDidLoad'una ekleyin:

[segmentedButton removeSegmentAtIndex:1 animated:NO];

Artık, belirtilen arka plan rengine sahip güzel, parlak, renkli bir düğmeniz var. Eylemler için 'değer değiştirildi' olayını kullanın.

(Bunu http://chris-software.com/index.php/2009/05/13/creating-a-nice-glass-buttons/ adresinde buldum ). Teşekkürler Chris!


5

Ben% 99 pozitifim, öylece gidip bir UIB düğmesinin arka plan rengini değiştiremezsiniz. Bunun yerine, arka plan resimlerini kendiniz değiştirmelisiniz ki bunun bir acı olduğunu düşünüyorum. Bunu yapmak zorunda olduğuma şaşırdım.

Yanılıyorsam veya arka plan resimlerini ayarlamak zorunda kalmadan daha iyi bir yol varsa lütfen bana bildirin

[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];

5
Kesinlikle haklısın. Bu bir acı ve görüntü oluşturma zahmeti yerine yapılması birkaç dakika alması gereken bir şey. Artı düğmeniz yuvarlaksa, bunu yapmak daha da zorlaşır ... Çok acı.
Henley Chiu

2

@EthanB önerisi ve @karim geri dolgulu bir dikdörtgen oluştururken, bunu başarmak için UIButton için bir kategori oluşturdum.

Kategori kodunu girmeniz yeterlidir: https://github.com/zmonteca/UIButton-PLColor

Kullanım:

[button setBackgroundColor:uiTextColor forState:UIControlStateDisabled];

ForStates'in kullanılması için isteğe bağlı:

UIControlStateNormal
UIControlStateHighlighted
UIControlStateDisabled
UIControlStateSelected

2

Ayrıca düğmeye bir CALayer da ekleyebilirsiniz - bunlarla renk kaplaması dahil birçok şey yapabilirsiniz, bu örnekte düz bir renk katmanı kullanılır ve ayrıca rengi kolayca derecelendirebilirsiniz. Eklenen katmanlar altındakileri gizlese de unutmayın

+(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];

}

Parlak!!!!!! Ancak aynı düğmeye karşı birkaç kez çağrılamaz. Olabilir, ancak yeni katmanlar tekrar tekrar eklenir.
Valeriy Van

@StanJames: Kodda yapılacak düzenlemeler bir yorumla (veya uygunsa, kendi cevabınızla) önerilmelidir.
mafso

1

için ikinci hedefi eklemek UIButtoniçin UIControlEventTouchedve değişim UIButtonarka plan rengini. Sonra UIControlEventTouchUpInsidehedefe geri döndürün;


1

Profesyonel ve hoş görünümlü düğmeler için, bu özel düğme bileşenini kontrol edebilirsiniz . Bunu doğrudan görünümlerinizde ve tablo görünümlerinizde kullanabilir veya ihtiyaçlarınızı karşılaması için kaynak kodunu değiştirebilirsiniz. Bu yardımcı olur umarım.


1

Bu, UIButton alt sınıflandırma kadar zarif değil, ancak hızlı bir şey istiyorsanız - yaptığım şey özel bir düğme oluşturmak, ardından düğmenin olmasını istediğim renge sahip 1 piksele 1 piksellik bir resim oluşturmak ve arka planı ayarlamaktı vurgulanan durum için o görüntünün düğmesinin - ihtiyaçlarım için çalışıyor.


1

Bunun uzun zaman önce sorulduğunu biliyorum ve şimdi yeni bir UIButtonTypeSystem var. Ancak daha yeni sorular bu sorunun kopyaları olarak işaretleniyor, bu nedenle iOS 7 sistem düğmesi bağlamındaki yeni cevabım .tintColorözelliği kullanın .

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

0

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

Bu şekilde değiştirmek veya Storyboard'a gitmek ve sağ taraftaki seçeneklerin arka planını değiştirmek mümkündür.


0

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

Oraya koyduğunuz kodu nasıl çağıracağınızı veya kullanacağınızı söylerseniz, bu çok daha yararlı bir cevap olacaktır. Bir UIButton uzantısına giriyor mu?
Michael Dautermann
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.