เป็นไปได้ไหมที่จะเปลี่ยนสีพื้นหลัง UIButtons


105

หนึ่งนี้ทำให้ฉันนิ่งงัน

เป็นไปได้หรือไม่ที่จะเปลี่ยนสีพื้นหลังของ UIButton ใน Cocoa สำหรับ iPhone ฉันได้ลองตั้งค่าสีพื้นหลังแล้ว แต่เปลี่ยนเฉพาะมุมเท่านั้น setBackgroundColor:ดูเหมือนจะเป็นวิธีเดียวที่ใช้ได้สำหรับสิ่งเหล่านี้

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

คุณสามารถแก้ไขภาพหรือลบออกได้หรือไม่ kthx;)
stigi

o-0 อืม ..... ภาพก็ใช้ได้ แต่ตอนนี้ไม่ปรากฏอีกแล้ว เพิ่งลบไป
dubbeat

นี่คือสำเนาของstackoverflow.com/questions/372731/…
Brad Larson

ฉันแก้ปัญหานี้ในโพสต์ทั่วไปของฉันโปรดตรวจสอบลิงก์ [เปลี่ยนเส้นขอบหรือพื้นหลังของ UIButton แบบไดนามิก] [1] [1]: stackoverflow.com/questions/9733213/…
IMMORTAL

พบบทแนะนำและโค้ดตัวอย่างที่ดีที่นี่cimgf.com/2010/01/28/…
Shamsudheen TK

คำตอบ:


160

ซึ่งสามารถทำได้โดยการเขียนโปรแกรมโดยสร้างแบบจำลอง:

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;

แก้ไข: แน่นอนคุณต้อง #import <QuartzCore/QuartzCore.h>

แก้ไข: สำหรับผู้อ่านใหม่ทุกคนคุณควรพิจารณาตัวเลือกสองสามตัวที่เพิ่มเป็น "ความเป็นไปได้อื่น" เพื่อให้คุณพิจารณา

เนื่องจากนี่เป็นคำตอบเก่าเราขอแนะนำให้อ่านความคิดเห็นเพื่อแก้ไขปัญหา


นี่คือสิ่งที่ OP กำลังมองหา
Steven

4
หวาน! ในบรรดาสารละลายทั้งหมดที่ฉันพบนี่คือสิ่งที่ฉันไปด้วย เพื่อเป็นการชี้แจงการสร้าง 'แบบจำลอง' หมายถึงการใช้ควอตซ์เพื่อวาดรูปสี่เหลี่ยมผืนผ้าโค้งมนในปุ่มที่กำหนดเองแทนที่จะใช้ปุ่มแบบ RoundedRect ตอนแรกฉันคิดว่ามันหมายถึงการทำสำเนาสี่เหลี่ยมผืนผ้าโค้งมนที่มีสีอื่นเพื่อจำลองการเปลี่ยนสี bg
daver

1
ทำงานได้อย่างสมบูรณ์ตอบโจทย์ OP ได้ดีที่สุด ขอบคุณสำหรับการแบ่งปัน.
รำ

@daver: คำตอบนี้ดังมากต้องมีบุญฉันหายไป เราจะเปลี่ยนสีพื้นหลังตามสถานะได้อย่างไร? สันนิษฐานว่าต้องเปลี่ยนสีพื้นหลังอย่างชัดเจนทุกครั้งที่เปลี่ยนสถานะ ปุ่มของฉันถูกปิดใช้งานเมื่อกดจนกว่าบริการเว็บจะตอบสนอง ฉันต้องเปลี่ยนเพื่อเน้นสีเมื่อกดและมีตัวจับเวลาเปลี่ยนเป็นสีที่ปิดใช้งานในขณะที่รอให้ ws ตอบสนองหรือไม่? หากฉันพลาดจุดนี้ได้โปรดอธิบาย ขอบคุณพอลลี่
Polly

1
@Polly: ขออภัยไม่เห็นความคิดเห็นของคุณเร็วกว่านี้ แต่ถ้าคุณยังสนใจนี่คือสิ่งที่ฉันทำ: subclass UIButton และแทนที่ drawRect: เพื่อวาดรูปสี่เหลี่ยมผืนผ้าโค้งมนโดยใช้ UIBezierPaths หลังจากวาดแล้วให้เติมด้วยการไล่ระดับสีโดยใช้ CGGradientCreateWithColorComponents () หนึ่งในอาร์เรย์ของฟังก์ชันนี้คืออาร์เรย์องค์ประกอบ 4 โฟลต (สอดคล้องกับ R, G, B และอัลฟา) ฉันยกเลิกอาร์เรย์สี 2 อาร์เรย์หนึ่งรายการสำหรับแต่ละสถานะและเลือกอันที่เหมาะสมใน drawRect ตามสถานะปุ่ม
daver

59

ฉันมีวิธีการที่แตกต่างออกไป

[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

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

อย่าลืม #import <QuartzCore/QuartzCore.h>


2
ทำได้ดีนี่. ฉันพบว่าฉันต้องเพิ่มbtFind.layer.borderWidth = 1;
DefenestrationDay

ฉันชอบโซลูชันนี้ แต่ในขณะนี้ฉันไม่สามารถใช้งานได้ ฉันได้รับข้อผิดพลาดเนื่องจากไม่พบ "CommonUIUtility" Google แค่ให้สิ่งของคราสแก่ฉัน แต่ฉันเดาว่ามันน่าจะอยู่ใน QuartzCore? ความคิดใด ๆ ?
Stephan

ไม่นั่นเป็นคลาสที่ผู้ใช้กำหนดสำหรับการทำ UI ทั่วไปในแอป คุณเขียนเมธอด imageFromColor ในคลาสของคุณเอง
karim

1
กลิ่นเหมือนวิธีการในหมวดหมู่ setBackgroundColor:(UIColor *) forState:(UIControlState)UIButton:
EthanB

3
มันโง่มากที่เราใช้ iOS 7 และนี่เป็นวิธีที่สะอาดที่สุดในการเพิ่มสีพื้นหลัง
dmur

32

ฉันคิดว่าคุณกำลังพูดถึง UIButton กับUIButtonTypeRoundedRect? คุณไม่สามารถเปลี่ยนสีพื้นหลังได้ เมื่อคุณลองเปลี่ยนสีพื้นหลังคุณค่อนข้างจะเปลี่ยนสีของ rect ปุ่มจะถูกวาดขึ้น (ซึ่งโดยปกติจะชัดเจน) มีสองวิธีที่จะไป ไม่ว่าคุณจะคลาสย่อย UIButton และเขียนทับ-drawRect:เมธอดหรือสร้างภาพสำหรับสถานะปุ่มต่างๆ (ซึ่งทำได้ดีมาก)

หากคุณตั้งค่าภาพพื้นหลังในตัวสร้างอินเทอร์เฟซคุณควรสังเกตว่า IB ไม่รองรับการตั้งค่าภาพสำหรับทุกสถานะที่ปุ่มสามารถมีได้ดังนั้นฉันขอแนะนำให้ตั้งค่ารูปภาพในโค้ดดังนี้:

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

บรรทัดสุดท้ายแสดงวิธีตั้งค่ารูปภาพสำหรับสถานะที่เลือก & ไฮไลต์ (นั่นคือสถานะที่ IB ไม่สามารถตั้งค่าได้) คุณไม่จำเป็นต้องใช้รูปภาพที่เลือก (บรรทัดที่ 4 และ 6) หากปุ่มคุณไม่ต้องการสถานะที่เลือก


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

2
ฉันเพิ่งค้นหา Google สั้น ๆ สำหรับ "iphone drawrect round corner" และพบสิ่งนี้: iphonedevelopment.blogspot.com/2008/11/… ตรวจสอบวิธีการวาดเพื่อดูตัวอย่างวิธีการวาดรูปสี่เหลี่ยมผืนผ้า คุณสามารถใช้CGContextSetFillColorWithColorและเพื่อเติมเต็มเส้นทางที่วาดโดยCGContextFillPath CGContextAddArcToPoint
stigi

2
+50 เพื่อชี้ให้เห็นถึงศักยภาพของ bitmasking สำหรับสถานะการควบคุมเช่น: forState:(UIControlStateHighlighted | UIControlStateSelected)ไชโย
NSTJ

28

ความเป็นไปได้อื่น:

  1. สร้าง UIButton ในตัวสร้างอินเทอร์เฟซ
  2. กำหนดประเภท 'กำหนดเอง'
  3. ตอนนี้ใน IB สามารถเปลี่ยนสีพื้นหลังได้

อย่างไรก็ตามปุ่มเป็นสี่เหลี่ยมจัตุรัสและนั่นไม่ใช่สิ่งที่เราต้องการ สร้าง IBOutlet โดยอ้างอิงถึงปุ่มนี้และเพิ่มสิ่งต่อไปนี้ในเมธอด viewDidLoad:

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

อย่าลืมนำเข้า QuartzCore.h


7
สมบูรณ์แบบขอบคุณ! ฉันไม่แน่ใจว่าเป็นเพราะ iOS เวอร์ชันที่ฉันใช้ (5.1) แต่ setClipToBounds ไม่พร้อมใช้งาน แต่ฉันใช้ buttonOutlet.layer.masksToBounds = TRUE;
iforce2d

เมื่อฉันเพิ่มรหัสนี้มันจะแสดงรูปสี่เหลี่ยมผืนผ้าโค้งมน แต่เมื่อฉันคลิกที่มันปุ่มจะไม่ย้อนกลับไฮไลต์ เกิดอะไรขึ้น?
จะ

ปัญหาของวิธีนี้คือคุณไม่สามารถกำหนดสีพื้นหลังสำหรับสถานะที่ไฮไลต์ของปุ่มได้
ch3rryc0ke

17

Subclass UIButton และแทนที่ setHighlighted และ 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];
}

เมธอด darkShade ของฉันอยู่ในหมวด UIColor แบบนี้

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

UIButton สี

หากคุณไม่ต้องการใช้รูปภาพและต้องการให้ดูเหมือนกับรูปแบบสี่เหลี่ยมผืนผ้าโค้งมนให้ลองทำเช่นนี้ เพียงแค่วาง UIView ไว้เหนือ UIButton โดยมีกรอบที่เหมือนกันและมาสก์ปรับขนาดอัตโนมัติตั้งค่าอัลฟาเป็น 0.3 และตั้งค่าพื้นหลังเป็นสี จากนั้นใช้ตัวอย่างด้านล่างเพื่อตัดขอบโค้งมนออกจากมุมมองภาพซ้อนทับสี นอกจากนี้ให้ยกเลิกการเลือกช่องทำเครื่องหมาย "เปิดใช้งานการโต้ตอบกับผู้ใช้" ใน IB บน UIView เพื่อให้เหตุการณ์การสัมผัสเรียงซ้อนลงไปที่ UIButton ที่อยู่ด้านล่าง

ผลข้างเคียงอย่างหนึ่งคือข้อความของคุณจะถูกทำให้เป็นสีด้วย

#import <QuartzCore/QuartzCore.h>

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

7

ความเป็นไปได้อีกอย่าง (imho ที่ดีที่สุดและสวยงามที่สุด):

สร้าง UISegmentedControl ที่มี 2 เซ็กเมนต์ในสีพื้นหลังที่ต้องการใน Interface Builder ตั้งค่าประเภทเป็น 'bar' จากนั้นเปลี่ยนให้มีเพียงกลุ่มเดียว ตัวสร้างอินเทอร์เฟซไม่ยอมรับหนึ่งเซ็กเมนต์ดังนั้นคุณต้องทำแบบนั้นโดยใช้โปรแกรม

ดังนั้นให้สร้าง IBOutlet สำหรับปุ่มนี้และเพิ่มเข้าไปใน viewDidLoad ของมุมมองของคุณ:

[segmentedButton removeSegmentAtIndex:1 animated:NO];

ตอนนี้คุณมีปุ่มสีมันวาวสวยงามพร้อมสีพื้นหลังที่ระบุ สำหรับการดำเนินการให้ใช้เหตุการณ์ "ค่าที่เปลี่ยนแปลง"

(ฉันพบสิ่งนี้ในhttp://chris-software.com/index.php/2009/05/13/creating-a-nice-glass-buttons/ ) ขอบคุณคริส!


5

ฉันคิดบวก 99% ที่คุณไม่สามารถเปลี่ยนสีพื้นหลังของ UIButton ได้ แต่คุณต้องไปเปลี่ยนภาพพื้นหลังด้วยตัวเองซึ่งฉันคิดว่ามันเป็นความเจ็บปวด ฉันประหลาดใจที่ฉันต้องทำเช่นนี้

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

[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
คุณพูดถูกจริงๆ มันเป็นความเจ็บปวดและสิ่งที่ควรใช้เวลาสักครู่เพื่อทำแทนความยุ่งยากในการสร้างภาพ ยิ่งถ้าปุ่มของคุณกลมก็ยิ่งทำให้ยากขึ้นอีกด้วย ...
Henley Chiu

2

ตามคำแนะนำของ @EthanB และ @karim สร้างรูปสี่เหลี่ยมผืนผ้าด้านหลังฉันเพิ่งสร้างหมวดหมู่สำหรับ UIButton เพื่อให้บรรลุสิ่งนี้

เพียงแค่ใส่รหัสหมวดหมู่: https://github.com/zmonteca/UIButton-PLColor

การใช้งาน:

[button setBackgroundColor:uiTextColor forState:UIControlStateDisabled];

ทางเลือกสำหรับรัฐที่จะใช้:

UIControlStateNormal
UIControlStateHighlighted
UIControlStateDisabled
UIControlStateSelected

2

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

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

}

แจ่ม !!!!!! แต่ไม่สามารถเรียกหลายครั้งกับปุ่มเดียวกัน ทำได้ แต่มีการเพิ่มเลเยอร์ใหม่ครั้งแล้วครั้งเล่า
Valeriy Van

@StanJames: การแก้ไขโค้ดควรได้รับการแนะนำโดยความคิดเห็น (หรือหากเหมาะสมโดยคำตอบของคุณเอง)
mafso

1

เพิ่มเป้าหมายที่สองสำหรับUIButtonสำหรับUIControlEventTouchedและเปลี่ยนUIButtonสีพื้นหลัง จากนั้นเปลี่ยนกลับในUIControlEventTouchUpInsideเป้าหมาย


1

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


1

สิ่งนี้ไม่หรูหราเท่า UIButton แบบย่อย แต่ถ้าคุณต้องการบางสิ่งบางอย่างที่รวดเร็วสิ่งที่ฉันทำคือสร้างปุ่มที่กำหนดเองจากนั้นภาพ 1px x 1px ที่มีสีที่ฉันต้องการให้ปุ่มเป็นและตั้งค่าพื้นหลัง ของปุ่มไปยังรูปภาพนั้นสำหรับสถานะที่ไฮไลต์ - ใช้ได้กับความต้องการของฉัน


1

ฉันรู้ว่าสิ่งนี้ถูกถามมานานแล้วและตอนนี้มี UIButtonTypeSystem ใหม่ แต่คำถามที่ใหม่กว่าถูกทำเครื่องหมายว่าซ้ำกับคำถามนี้ดังนั้นนี่คือคำตอบใหม่ของฉันในบริบทของปุ่มระบบ iOS 7 ให้ใช้.tintColorคุณสมบัติ

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

เป็นไปได้ที่จะเปลี่ยนวิธีนี้หรือไปที่ Storyboard และเปลี่ยนพื้นหลังของตัวเลือกทางด้านขวา


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)

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