ฉันจะสร้าง UIColor จากสตริงฐานสิบหกได้อย่างไร


543

ฉันจะสร้างรูปแบบสตริงUIColorจากเลขฐานสิบหกได้#00FF00อย่างไร


เอริก้านอกจากนี้ยังมีประเภทการขยายสีที่ดีสำหรับ iOS และ OSX
Echilon

นี่คือห้องสมุดอื่น: github.com/burhanuddin353/TFTColor
Burhanuddin Sunelwala

คำตอบ:


722

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

#define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]

แมโคร uicolor ที่มีค่าฐานสิบหก

รุ่นที่จัดรูปแบบของรหัสนี้ด้วย:

#define UIColorFromRGB(rgbValue) \
[UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 \
                green:((float)((rgbValue & 0x00FF00) >>  8))/255.0 \
                 blue:((float)((rgbValue & 0x0000FF) >>  0))/255.0 \
                alpha:1.0]

การใช้งาน:

label.textColor = UIColorFromRGB(0xBC1128);

130
สิ่งนี้ดีมากยกเว้นจะไม่ทำในสิ่งที่ผู้ถามถามซึ่งเป็นการแปลง hex STRING เป็น UIColor สิ่งนี้จะแปลงจำนวนเต็มเป็น UIColor
darrinm

31
@ MohamedA.Karim นั่นเป็นตัวอย่างของการส่งคืน UIColor จากจำนวนเต็มรูปแบบฐานสิบหก (0x ... ) ไม่ใช่สตริงรูปแบบฐานสิบหก ("# ... ") ดีมากถ้านั่นคือสิ่งที่คุณต้องการ แต่ไม่ใช่สิ่งที่ผู้ถามถาม
darrinm

3
@ScottKohlert บรรทัดโค้ดของคุณแปลงสตริงรูปแบบฐานสิบหกหนึ่งสตริง (นำหน้าด้วย "#") เป็นสตริงรูปแบบฐานสิบหกอื่น (นำหน้าด้วย "0x") มันไม่ได้ผลิตจำนวนเต็ม
darrinm

1
วิธีการใช้งานเช่น [UIColor whiteColor] .CGColor
SleepNot

3
การแปลงรูปแบบของสตริงฐานสิบหกเป็นจำนวนเต็มสำหรับใช้กับแมโครนี้ดูstackoverflow.com/questions/3648411/...
devios1

371

โซลูชันที่รัดกุม:

// Assumes input like "#00FF00" (#RRGGBB).
+ (UIColor *)colorFromHexString:(NSString *)hexString {
    unsigned rgbValue = 0;
    NSScanner *scanner = [NSScanner scannerWithString:hexString];
    [scanner setScanLocation:1]; // bypass '#' character
    [scanner scanHexInt:&rgbValue];
    return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0 green:((rgbValue & 0xFF00) >> 8)/255.0 blue:(rgbValue & 0xFF)/255.0 alpha:1.0];
}

1
และวิธีการที่ดีสำหรับการแปลงแบบย้อนกลับ (เช่นถ้าคุณเก็บสีไว้ในแกนข้อมูล / ฐานข้อมูลระยะไกล) สามารถพบได้ที่นี่ - stackoverflow.com/questions/11884227/ …
Eric Goldberg

1
ทางออกที่สมบูรณ์แบบ หากสตริงเลขฐานสิบหกของคุณมาจาก API (มีเอกสารไม่ดีมาก) ต้องแน่ใจว่าได้ทดสอบกับรหัสฐานสิบหกแบบย่อเช่น #FFF หรือ # FC0 คุณจะต้องเปลี่ยนเป็น # FFFFFF / # FFCCOO
Patrick

10
คุณอาจต้องการเพิ่มif ( [hexString rangeOfString:@"#"].location == 0 )ก่อนsetScanLocationบรรทัดเพื่อสร้างทาง#เลือก
devios1

คุณช่วยเพิ่มวิธีย้อนกลับได้ไหม
hasan

11
สำหรับคนขี้เกียจ: SWIFTรุ่นที่นี่
fabian789

188

ฉันมีวิธีแก้ปัญหาที่เข้ากันได้ 100% กับสตริงรูปแบบฐานสิบหกที่ใช้โดย Android ซึ่งฉันพบว่ามีประโยชน์มากเมื่อทำการพัฒนาอุปกรณ์เคลื่อนที่ข้ามแพลตฟอร์ม มันช่วยให้ฉันใช้เพดานหนึ่งสีสำหรับทั้งสองแพลตฟอร์ม อย่าลังเลที่จะใช้ซ้ำโดยไม่ต้องระบุแหล่งที่มาหรือภายใต้สัญญาอนุญาต Apache หากคุณต้องการ

#import "UIColor+HexString.h"

@interface UIColor(HexString)

+ (UIColor *) colorWithHexString: (NSString *) hexString;
+ (CGFloat) colorComponentFrom: (NSString *) string start: (NSUInteger) start length: (NSUInteger) length;

@end


@implementation UIColor(HexString)

+ (UIColor *) colorWithHexString: (NSString *) hexString {
    NSString *colorString = [[hexString stringByReplacingOccurrencesOfString: @"#" withString: @""] uppercaseString];
    CGFloat alpha, red, blue, green;
    switch ([colorString length]) {
        case 3: // #RGB
            alpha = 1.0f;
            red   = [self colorComponentFrom: colorString start: 0 length: 1];
            green = [self colorComponentFrom: colorString start: 1 length: 1];
            blue  = [self colorComponentFrom: colorString start: 2 length: 1];
            break;
        case 4: // #ARGB
            alpha = [self colorComponentFrom: colorString start: 0 length: 1];
            red   = [self colorComponentFrom: colorString start: 1 length: 1];
            green = [self colorComponentFrom: colorString start: 2 length: 1];
            blue  = [self colorComponentFrom: colorString start: 3 length: 1];          
            break;
        case 6: // #RRGGBB
            alpha = 1.0f;
            red   = [self colorComponentFrom: colorString start: 0 length: 2];
            green = [self colorComponentFrom: colorString start: 2 length: 2];
            blue  = [self colorComponentFrom: colorString start: 4 length: 2];                      
            break;
        case 8: // #AARRGGBB
            alpha = [self colorComponentFrom: colorString start: 0 length: 2];
            red   = [self colorComponentFrom: colorString start: 2 length: 2];
            green = [self colorComponentFrom: colorString start: 4 length: 2];
            blue  = [self colorComponentFrom: colorString start: 6 length: 2];                      
            break;
        default:
            [NSException raise:@"Invalid color value" format: @"Color value %@ is invalid.  It should be a hex value of the form #RBG, #ARGB, #RRGGBB, or #AARRGGBB", hexString];
            break;
    }
    return [UIColor colorWithRed: red green: green blue: blue alpha: alpha];
}

+ (CGFloat) colorComponentFrom: (NSString *) string start: (NSUInteger) start length: (NSUInteger) length {
    NSString *substring = [string substringWithRange: NSMakeRange(start, length)];
    NSString *fullHex = length == 2 ? substring : [NSString stringWithFormat: @"%@%@", substring, substring];
    unsigned hexComponent;
    [[NSScanner scannerWithString: fullHex] scanHexInt: &hexComponent];
    return hexComponent / 255.0;
}

@end 

3
ในcolorComponentFrom:start:length:คุณไม่ควรreturn hexComponent / 0xFF; // divide by 255, not 256? ค่าฐานสิบหกที่ใหญ่ที่สุดที่คุณควรได้รับคือ 0xFF ดังนั้นนั่นคือสิ่งที่คุณควรหารด้วย 0xFF (255)
แซม

จับได้ดีแซม แก้ไขเพื่อให้สอดคล้องกับการเปลี่ยนแปลง
คาห์ Hainline

6
นี่มันเยี่ยมมากไชโย นอกจากนี้แทนที่จะจัดหมวดหมู่บน UIColor คุณสามารถสร้าง NSString ให้มีรูปแบบดังนี้[@"#538aa4" toColor]
Dan2552

2
โซลูชันนี้ยอดเยี่ยมฉันขอแนะนำให้เพิ่ม "ส่วนตัว" สำหรับชื่อของอินเทอร์เฟซส่วนตัวเพื่อหลีกเลี่ยงคำเตือนคอมไพเลอร์ @interface UIColor (ส่วนตัว)
djleop

1
ดี คุณควรใส่ฟังก์ชั่นอื่น ๆในส่วนต่อประสาน
Bjorn Roche

63

มีโพสต์ที่ดีเกี่ยวกับวิธีจัดการปัญหาของ OP ในการแยก a UIColorจากสตริงฐานสิบหก โซลูชันที่นำเสนอด้านล่างแตกต่างจากโซลูชันอื่นเนื่องจากสนับสนุนค่าสตริงที่อาจมี '0x' หรือ '#' นำหน้าด้วยการแสดงสตริง hex ... (ดูการใช้งาน)

นี่คือบิตหลัก ...

- (UIColor *)getUIColorObjectFromHexString:(NSString *)hexStr alpha:(CGFloat)alpha
{
  // Convert hex string to an integer
  unsigned int hexint = [self intFromHexString:hexStr];

  // Create a color object, specifying alpha as well
  UIColor *color =
    [UIColor colorWithRed:((CGFloat) ((hexint & 0xFF0000) >> 16))/255
    green:((CGFloat) ((hexint & 0xFF00) >> 8))/255
    blue:((CGFloat) (hexint & 0xFF))/255
    alpha:alpha];

  return color;
}

วิธีใช้ตัวช่วย ...

- (unsigned int)intFromHexString:(NSString *)hexStr
{
  unsigned int hexInt = 0;

  // Create scanner
  NSScanner *scanner = [NSScanner scannerWithString:hexStr];

  // Tell scanner to skip the # character
  [scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"#"]];

  // Scan hex value
  [scanner scanHexInt:&hexInt];

  return hexInt;
}

การใช้งาน:

NSString *hexStr1 = @"123ABC";
NSString *hexStr2 = @"#123ABC";
NSString *hexStr3 = @"0x123ABC";

UIColor *color1 = [self getUIColorObjectFromHexString:hexStr1 alpha:.9];
NSLog(@"UIColor: %@", color1);

UIColor *color2 = [self getUIColorObjectFromHexString:hexStr2 alpha:.9];
NSLog(@"UIColor: %@", color2);

UIColor *color3 = [self getUIColorObjectFromHexString:hexStr3 alpha:.9];
NSLog(@"UIColor: %@", color3);

บทความอ้างอิงฉบับสมบูรณ์

Swift 2+

ฉันได้แจ้งวิธีแก้ปัญหานี้กับ Swift 2.2 แล้ว โปรดทราบว่าฉันได้เปลี่ยนalphaพารามิเตอร์เพื่อใช้ชุดเริ่มต้นเป็น 1.0 ฉันได้อัปเดตประเภท int UInt32เป็นตามที่NSScannerชั้นเรียนต้องการใน Swift 2.2

func colorWithHexString(hexString: String, alpha:CGFloat = 1.0) -> UIColor {

    // Convert hex string to an integer
    let hexint = Int(self.intFromHexString(hexString))
    let red = CGFloat((hexint & 0xff0000) >> 16) / 255.0
    let green = CGFloat((hexint & 0xff00) >> 8) / 255.0
    let blue = CGFloat((hexint & 0xff) >> 0) / 255.0 

    // Create color object, specifying alpha as well
    let color = UIColor(red: red, green: green, blue: blue, alpha: alpha)
    return color
}

func intFromHexString(hexStr: String) -> UInt32 {
    var hexInt: UInt32 = 0
    // Create scanner
    let scanner: NSScanner = NSScanner(string: hexStr)
    // Tell scanner to skip the # character
    scanner.charactersToBeSkipped = NSCharacterSet(charactersInString: "#")
    // Scan hex value
    scanner.scanHexInt(&hexInt)
    return hexInt
}

Swift 4+

ใช้ตรรกะเดียวกันกับการเปลี่ยนแปลงที่ใช้กับ swift 4

func colorWithHexString(hexString: String, alpha:CGFloat = 1.0) -> UIColor {

    // Convert hex string to an integer
    let hexint = Int(self.intFromHexString(hexStr: hexString))
    let red = CGFloat((hexint & 0xff0000) >> 16) / 255.0
    let green = CGFloat((hexint & 0xff00) >> 8) / 255.0
    let blue = CGFloat((hexint & 0xff) >> 0) / 255.0

    // Create color object, specifying alpha as well
    let color = UIColor(red: red, green: green, blue: blue, alpha: alpha)
    return color
}

func intFromHexString(hexStr: String) -> UInt32 {
    var hexInt: UInt32 = 0
    // Create scanner
    let scanner: Scanner = Scanner(string: hexStr)
    // Tell scanner to skip the # character
    scanner.charactersToBeSkipped = CharacterSet(charactersIn: "#")
    // Scan hex value
    scanner.scanHexInt32(&hexInt)
    return hexInt
}

การอ้างอิง Hex สี

ชื่อและรหัสสี HTML

รหัสสีฐานสิบหก


ตัวอย่าง Swift ที่โพสต์ที่นี่ดูเหมือนจะเข้าใจผิดวัตถุประสงค์ของ optionals ใน Swift ซึ่งมีค่าที่อาจไม่มีอยู่จริง คำถามที่ถามว่าพารามิเตอร์ต้องเป็นตัวเลือกหรือไม่ว่ามีบางคนอาจต้องการความสามารถในการตั้งค่าเป็นศูนย์หรือไม่ มันไม่อาจทำให้ความรู้สึกalphaที่จะเคยถูกตั้งค่าเป็นศูนย์? เพราะวิธีนี้ทำให้คนมีความสามารถนั้นและถ้าใครบางคนควรตัดสินใจที่alphaจะเป็นศูนย์การบังคับไม่เลือกตัวเลือกนั้นจะนำไปสู่ความผิดพลาดอย่างสม่ำเสมอ ฉันยังไม่ได้แก้ไขมัน แต่ในกรณีที่มีเหตุผลบางอย่างที่ฉันไม่ทราบ
Jonathan Thornton

@JonathanThornton - ขอบคุณสำหรับหัวขึ้น การแก้ไข
Tommie C.

การทำงานในโครงการดั้งเดิมและโซลูชัน Objective-C ทำงานได้ดีมาก ... ยกเว้น ... ผิดปกติ ... @ "# ffc107" และ @ "# e040fb" ปฏิเสธที่จะร่วมมือ! คิด?
นาธาเนียล

51

นี่คือฟังก์ชั่นที่รับสตริง hex และส่งกลับ UIColor
(คุณสามารถป้อนสตริง hex ได้ทั้งสองรูปแบบ: #ffffffหรือffffff)

การใช้งาน:

var color1 = hexStringToUIColor("#d3d3d3")

สวิฟท์ 4:

func hexStringToUIColor (hex:String) -> UIColor {
    var cString:String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()

    if (cString.hasPrefix("#")) {
        cString.remove(at: cString.startIndex)
    }

    if ((cString.count) != 6) {
        return UIColor.gray
    }

    var rgbValue:UInt32 = 0
    Scanner(string: cString).scanHexInt32(&rgbValue)

    return UIColor(
        red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
        green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
        blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
        alpha: CGFloat(1.0)
    )
}

สวิฟท์ 3:

func hexStringToUIColor (hex:String) -> UIColor {
    var cString:String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()

    if (cString.hasPrefix("#")) {
        cString.remove(at: cString.startIndex)
    }

    if ((cString.characters.count) != 6) {
        return UIColor.gray
    }

    var rgbValue:UInt32 = 0
    Scanner(string: cString).scanHexInt32(&rgbValue)

    return UIColor(
        red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
        green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
        blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
        alpha: CGFloat(1.0)
    )
}

สวิฟท์ 2:

func hexStringToUIColor (hex:String) -> UIColor {
    var cString:String = hex.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet() as NSCharacterSet).uppercaseString

    if (cString.hasPrefix("#")) {
      cString = cString.substringFromIndex(cString.startIndex.advancedBy(1))
    }

    if ((cString.characters.count) != 6) {
      return UIColor.grayColor()
    }

    var rgbValue:UInt32 = 0
    NSScanner(string: cString).scanHexInt(&rgbValue)

    return UIColor(
        red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
        green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
        blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
        alpha: CGFloat(1.0)
    )
}



ที่มา: arshad / ส่วนสำคัญ: de147c42d7b3063ef7bc


ฉันเคยเห็นใน SVG แล้วซึ่งมีสตริง hex ขนาดเล็กที่มี 3 ตัวอักษรเช่น # F0F
Glenn Howes

นั่นคือรูปแบบย่อโดยที่ '# F0F' เทียบเท่ากับ '# FF00FF' มันจะง่ายในการเขียนฟังก์ชั่นที่ตรวจสอบการจดชวเลขและขยาย
Ethan Strider

38

ใช้หมวดหมู่นี้:

ในไฟล์UIColor + Hexadecimal.h

#import <UIKit/UIKit.h>

@interface UIColor(Hexadecimal)

+ (UIColor *)colorWithHexString:(NSString *)hexString;

@end

ในไฟล์UIColor + Hexadecimal.m

#import "UIColor+Hexadecimal.h"

@implementation UIColor(Hexadecimal)

+ (UIColor *)colorWithHexString:(NSString *)hexString {
    unsigned rgbValue = 0;
    NSScanner *scanner = [NSScanner scannerWithString:hexString];
    [scanner setScanLocation:1]; // bypass '#' character
    [scanner scanHexInt:&rgbValue];

    return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0 green:((rgbValue & 0xFF00) >> 8)/255.0 blue:(rgbValue & 0xFF)/255.0 alpha:1.0];
}

@end

ในชั้นเรียนที่คุณต้องการใช้:

#import "UIColor+Hexadecimal.h"

และ:

[UIColor colorWithHexString:@"#6e4b4b"];

ไม่มีการจัดการอัลฟา
Ihor Klimov

28

การใช้งาน Swift ที่ยอดเยี่ยม (อัปเดตสำหรับ Xcode 7) โดยใช้ส่วนขยายดึงมาจากคำตอบและสถานที่ที่แตกต่างหลากหลาย คุณจะต้องใช้ส่วนขยายของสตริงในตอนท้าย

ใช้:

let hexColor = UIColor(hex: "#00FF00")

หมายเหตุ: ฉันเพิ่มตัวเลือกสำหรับ 2 หลักเพิ่มเติมไปยังจุดสิ้นสุดของค่าเลขฐานสิบหก 6 หลักมาตรฐานสำหรับช่องอัลฟา (ผ่านในมูลค่า00-99 ) หากสิ่งนี้ทำให้คุณขุ่นเคืองเพียงลบออก คุณสามารถใช้มันเพื่อส่งผ่านพารามิเตอร์ตัวเลือก

ส่วนขยาย:

extension UIColor {

    convenience init(var hex: String) {
        var alpha: Float = 100
        let hexLength = hex.characters.count
        if !(hexLength == 7 || hexLength == 9) {
            // A hex must be either 7 or 9 characters (#RRGGBBAA)
            print("improper call to 'colorFromHex', hex length must be 7 or 9 chars (#GGRRBBAA)")
            self.init(white: 0, alpha: 1)
            return
        }

        if hexLength == 9 {
            // Note: this uses String subscripts as given below
            alpha = hex[7...8].floatValue
            hex = hex[0...6]
        }

        // Establishing the rgb color
        var rgb: UInt32 = 0
        let s: NSScanner = NSScanner(string: hex)
        // Setting the scan location to ignore the leading `#`
        s.scanLocation = 1
        // Scanning the int into the rgb colors
        s.scanHexInt(&rgb)

        // Creating the UIColor from hex int
        self.init(
            red: CGFloat((rgb & 0xFF0000) >> 16) / 255.0,
            green: CGFloat((rgb & 0x00FF00) >> 8) / 255.0,
            blue: CGFloat(rgb & 0x0000FF) / 255.0,
            alpha: CGFloat(alpha / 100)
        )
    }
}

ส่วนขยายสตริง:
แหล่งที่มาตัวห้อยแหล่งที่มาของการลอย

extension String {

    /**
    Returns the float value of a string
    */
    var floatValue: Float {
        return (self as NSString).floatValue
    }

    /**
    Subscript to allow for quick String substrings ["Hello"][0...1] = "He"
    */
    subscript (r: Range<Int>) -> String {
        get {
            let start = self.startIndex.advancedBy(r.startIndex)
            let end = self.startIndex.advancedBy(r.endIndex - 1)
            return self.substringWithRange(start..<end)
        }
    }
}

คุณใช้ส่วนขยายสตริงเพื่อรับตัวย่อหรือไม่ เช่นstackoverflow.com/a/24144365/3220708
Craig Grummitt

@ CraigGrummitt โอ้ฉัน! ฮ่าฮ่าใช่ ฉันมีรายการส่วนขยายและตัวห้อยที่รวบรวมไว้บางครั้งฉัน (น่าเศร้า) ลืมสิ่งที่เป็นและไม่รวมอยู่ในชุดคุณลักษณะภาษามาตรฐาน ฉันอัปเดตคำตอบของฉันรวมถึงแหล่งที่คุณให้ ไม่แน่ใจว่าฉันได้รับจากที่นั่นหรือไม่ แต่ดูใกล้ ๆ
Firo

คุณอาจต้องการพูดถึงว่ามันเป็นส่วนขยายของสตริง นอกจากนี้คุณดูเหมือนจะพลาดส่วนขยาย String floatValue: stackoverflow.com/a/24088249/3220708นอกจากนั้นทำงานได้ดี!
Craig Grummitt

countElements () อยู่ที่ไหน func?
ΕГИІИО

countElements()ถูกแทนที่ด้วยcount()ใน Swift 1.2 มันถูกสร้างเป็นภาษา ฉันอัปเดตคำตอบเพื่อแสดงว่า
Firo

27

คุณสามารถสร้างส่วนขยายแบบนี้

extension UIColor{
    convenience init(rgb: UInt, alphaVal: CGFloat) {
        self.init(
            red: CGFloat((rgb & 0xFF0000) >> 16) / 255.0,
            green: CGFloat((rgb & 0x00FF00) >> 8) / 255.0,
            blue: CGFloat(rgb & 0x0000FF) / 255.0,
            alpha: alphaVal
        )
    }
}

และใช้งานได้ทุกที่เช่นนี้

UIColor(rgb: 0xffffff, alphaVal: 0.2)

ตายง่าย ๆ ที่ฉันชอบแน่นอน
ทฤษฎี

ขอบคุณอันนี้ยอดเยี่ยมมากกระชับกว่ากำแพงข้อความอื่น ๆ !
FrankByte.com

ฟังก์ชั่นที่ดี แต่มันไม่ตอบคำถาม
mah

@mah ตรงนี้เป็นคำถามที่ผมคิดว่าวิธีการสร้าง UIColor จาก hexstring
มนู Gupta

@ManuGupta คุณอาจสังเกตเห็นว่าไม่มีการจัดการสตริงในคำตอบนี้ ตัวเลขฐานสิบหกไม่ใช่สตริงฐานสิบหก คำถามที่ระบุสตริงอย่างชัดเจนและแม้ว่าจะไม่มีคำพูดอยู่ในนั้น#00FF00มีจุดมุ่งหมายที่ชัดเจนว่าเป็นสตริงอักขระ อย่างที่คนอื่น ๆ พูดกันว่าง่ายกระชับ แต่ถ้ามันไม่จัดการกับสตริงมันอาจไม่สามารถตอบคำถามที่ถามว่าจะจัดการกับสตริงได้อย่างไร
mah

26

ไม่มีการแปลง builtin จากสตริงเลขฐานสิบหกเป็นUIColor(หรือCGColor) ที่ฉันรู้ อย่างไรก็ตามคุณสามารถเขียนฟังก์ชั่นสำหรับวัตถุประสงค์นี้ได้อย่างง่ายดายตัวอย่างเช่นดูการพัฒนา iPhone ที่เข้าถึงส่วนประกอบ uicolor


3
+1 หากคุณเลื่อนลงวิธีที่เป็นปัญหาคือ + colorWithHexString:
Rob Napier

1
@RobNapier +colorWithHexString:ไม่ทำงาน อย่างน้อยในกรณีของฉัน :)
पवन

15

ผมพบว่าดีUIColorประเภทนี้PXExtensions UIColor

การใช้งาน: UIColor *mycolor = [UIColor pxColorWithHexValue:@"#BADA55"];

และในกรณีที่ลิงก์ไปยังส่วนสำคัญของฉันล้มเหลวนี่คือรหัสการใช้งานจริง:

//
//  UIColor+PXExtensions.m
//

#import "UIColor+UIColor_PXExtensions.h"

@implementation UIColor (UIColor_PXExtensions)

+ (UIColor*)pxColorWithHexValue:(NSString*)hexValue
{
    //Default
    UIColor *defaultResult = [UIColor blackColor];

    //Strip prefixed # hash
    if ([hexValue hasPrefix:@"#"] && [hexValue length] > 1) {
        hexValue = [hexValue substringFromIndex:1];
    }

    //Determine if 3 or 6 digits
    NSUInteger componentLength = 0;
    if ([hexValue length] == 3)
    {
        componentLength = 1;
    }
    else if ([hexValue length] == 6)
    {
        componentLength = 2;
    }
    else
    {
        return defaultResult;
    }

    BOOL isValid = YES;
    CGFloat components[3];

    //Seperate the R,G,B values
    for (NSUInteger i = 0; i < 3; i++) {
        NSString *component = [hexValue substringWithRange:NSMakeRange(componentLength * i, componentLength)];
        if (componentLength == 1) {
            component = [component stringByAppendingString:component];
        }
        NSScanner *scanner = [NSScanner scannerWithString:component];
        unsigned int value;
        isValid &= [scanner scanHexInt:&value];
        components[i] = (CGFloat)value / 256.0f;
    }

    if (!isValid) {
        return defaultResult;
    }

    return [UIColor colorWithRed:components[0]
                           green:components[1]
                            blue:components[2]
                           alpha:1.0];
}

@end

@PeterDuniho ตกลงฉันเพิ่มรหัสการนำไปปฏิบัติ :)
354 Hlung

13

รุ่นที่รวดเร็ว ใช้เป็นฟังก์ชั่นหรือส่วนขยาย

ฟังก์ชัน
  func UIColorFromRGB(colorCode: String, alpha: Float = 1.0) -> UIColor{
    var scanner = NSScanner(string:colorCode)
    var color:UInt32 = 0;
    scanner.scanHexInt(&color)

    let mask = 0x000000FF
    let r = CGFloat(Float(Int(color >> 16) & mask)/255.0)
    let g = CGFloat(Float(Int(color >> 8) & mask)/255.0)
    let b = CGFloat(Float(Int(color) & mask)/255.0)

    return UIColor(red: r, green: g, blue: b, alpha: CGFloat(alpha))
}
ส่วนขยาย
extension UIColor {
    convenience init(colorCode: String, alpha: Float = 1.0){
        var scanner = NSScanner(string:colorCode)
        var color:UInt32 = 0;
        scanner.scanHexInt(&color)

        let mask = 0x000000FF
        let r = CGFloat(Float(Int(color >> 16) & mask)/255.0)
        let g = CGFloat(Float(Int(color >> 8) & mask)/255.0)
        let b = CGFloat(Float(Int(color) & mask)/255.0)

        self.init(red: r, green: g, blue: b, alpha: CGFloat(alpha))
    }
}
วิธีการโทร
let hexColorFromFunction = UIColorFromRGB("F4C124", alpha: 1.0)
let hexColorFromExtension = UIColor(colorCode: "F4C124", alpha: 1.0)
คุณยังสามารถกำหนดของคุณHex Colorจากเครื่องมือสร้างอินเตอร์เฟส

ป้อนคำอธิบายรูปภาพที่นี่


12

นี่เป็นอีกทางเลือกหนึ่ง

- (UIColor *)colorWithRGBHex:(UInt32)hex
{
    int r = (hex >> 16) & 0xFF;
    int g = (hex >> 8) & 0xFF;
    int b = (hex) & 0xFF;

    return [UIColor colorWithRed:r / 255.0f
                           green:g / 255.0f
                            blue:b / 255.0f
                           alpha:1.0f];
}

คำตอบสำรองสำหรับคำถามสำรอง ... ไม่ใช่คำตอบที่สมเหตุสมผลสำหรับคำถามในหน้านี้
mah

11

คุณสามารถใช้เครื่องมือออนไลน์ต่าง ๆ เพื่อแปลงสตริง HEX เป็น UIColor จริง ตรวจสอบuicolor.orgหรือUI ตัวเลือกสี ผลลัพธ์จะถูกแปลงเป็นรหัส Objective-C เช่น:

[UIColor colorWithRed:0.93 green:0.80 blue:0.80 alpha:1.0];

ซึ่งคุณสามารถฝังในแอปพลิเคชันของคุณ หวังว่านี่จะช่วยได้!


อีกเครื่องมือออนไลน์ชื่อเดียวกันในความเป็นจริงUI ตัวเลือกสี
Joe

โดยทั่วไปเมื่อผู้คนขอความช่วยเหลือเกี่ยวกับรหัสในการแก้ปัญหาที่ค่อนข้างง่ายเช่นนี้คำตอบที่บอกว่า "ไปที่เว็บไซต์ออนไลน์บางแห่งเป็นครั้งแรก ... " ไม่ได้ใกล้เคียงกับคำตอบที่ผู้ถามต้องการ
mah

11

SWIFT 4

คุณสามารถสร้างconvenienceนวกรรมิกที่ดีในส่วนขยายเช่นนี้:

extension UIColor {
    convenience init(hexString: String, alpha: CGFloat = 1.0) {
        var hexInt: UInt32 = 0
        let scanner = Scanner(string: hexString)
        scanner.charactersToBeSkipped = CharacterSet(charactersIn: "#")
        scanner.scanHexInt32(&hexInt)

        let red = CGFloat((hexInt & 0xff0000) >> 16) / 255.0
        let green = CGFloat((hexInt & 0xff00) >> 8) / 255.0
        let blue = CGFloat((hexInt & 0xff) >> 0) / 255.0
        let alpha = alpha

        self.init(red: red, green: green, blue: blue, alpha: alpha)
    }
}

และใช้ในภายหลังเช่น

let color = UIColor(hexString: "#AABBCCDD")

'scanHexInt32' เลิกใช้แล้วใน iOS 13.0
Cosmo Arun

10
extension UIColor {
    convenience init(hexaString: String, alpha: CGFloat = 1) {
        let chars = Array(hexaString.dropFirst())
        self.init(red:   .init(strtoul(String(chars[0...1]),nil,16))/255,
                  green: .init(strtoul(String(chars[2...3]),nil,16))/255,
                  blue:  .init(strtoul(String(chars[4...5]),nil,16))/255,
                  alpha: alpha)}
}

การใช้งาน:

let redColor       = UIColor(hexaString: "#FF0000")              // r 1,0 g 0,0 b 0,0 a 1,0
let transparentRed = UIColor(hexaString: "#FF0000", alpha: 0.5)  // r 1,0 g 0,0 b 0,0 a 0,5

7

นี่เป็นสิ่งที่ดีด้วยการสนับสนุนcocoapod

https://github.com/mRs-/HexColors

// with hash
NSColor *colorWithHex = [NSColor colorWithHexString:@"#ff8942" alpha:1];

// wihtout hash
NSColor *secondColorWithHex = [NSColor colorWithHexString:@"ff8942" alpha:1];

// short handling
NSColor *shortColorWithHex = [NSColor colorWithHexString:@"fff" alpha:1]

พี่ชายของสวย ๆ :)
cesarferreira

4

อีกรุ่นที่มีอัลฟา

#define UIColorFromRGBA(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF000000) >> 24))/255.0 green:((float)((rgbValue & 0xFF0000) >> 16))/255.0 blue:((float)((rgbValue & 0xFF00) >> 8 ))/255.0 alpha:((float)((rgbValue & 0xFF))/255.0)]

4

รวดเร็วเทียบเท่ากับคำตอบของ @ Tom แม้ว่าจะได้รับค่า RGBA Int เพื่อสนับสนุนความโปร่งใส:

func colorWithHex(aHex: UInt) -> UIColor
{
    return UIColor(red: CGFloat((aHex & 0xFF000000) >> 24) / 255,
        green: CGFloat((aHex & 0x00FF0000) >> 16) / 255,
        blue: CGFloat((aHex & 0x0000FF00) >> 8) / 255,
        alpha: CGFloat((aHex & 0x000000FF) >> 0) / 255)
}

//usage
var color = colorWithHex(0x7F00FFFF)

และถ้าคุณต้องการที่จะใช้มันจากสตริงคุณสามารถใช้ strtoul:

var hexString = "0x7F00FFFF"

let num = strtoul(hexString, nil, 16)

var colorFromString = colorWithHex(num)

4

ต่อไปนี้เป็นรุ่นที่เขียนเป็นส่วนขยายไปSwift 1.2 UIColorสิ่งนี้ช่วยให้คุณทำ

let redColor = UIColor(hex: "#FF0000")

ซึ่งฉันรู้สึกว่าเป็นวิธีที่เป็นธรรมชาติที่สุดในการทำมัน

extension UIColor {
  // Initialiser for strings of format '#_RED_GREEN_BLUE_'
  convenience init(hex: String) {
    let redRange    = Range<String.Index>(start: hex.startIndex.advancedBy(1), end: hex.startIndex.advancedBy(3))
    let greenRange  = Range<String.Index>(start: hex.startIndex.advancedBy(3), end: hex.startIndex.advancedBy(5))
    let blueRange   = Range<String.Index>(start: hex.startIndex.advancedBy(5), end: hex.startIndex.advancedBy(7))

    var red     : UInt32 = 0
    var green   : UInt32 = 0
    var blue    : UInt32 = 0

    NSScanner(string: hex.substringWithRange(redRange)).scanHexInt(&red)
    NSScanner(string: hex.substringWithRange(greenRange)).scanHexInt(&green)
    NSScanner(string: hex.substringWithRange(blueRange)).scanHexInt(&blue)

    self.init(
      red: CGFloat(red) / 255,
      green: CGFloat(green) / 255,
      blue: CGFloat(blue) / 255,
      alpha: 1
    )
  }
}

ใน Xcode 6.3.2 บนบรรทัดที่ขึ้นต้นด้วยlet greenRange = ...ฉันได้รับการยกเว้น:fatal error: can not increment endIndex
Clifton Labrum

@CliftonLabrum ฉันได้ทำการทดสอบกับ Xcode 7 beta 3 แล้วและมันก็ใช้งานได้เหมือนกัน คุณยังประสบปัญหานี้อยู่หรือไม่
Morgan Wilde

3

การใช้งานอื่นอนุญาตให้ใช้สตริงเช่น"FFF"หรือหรือ"FFFFFF"ใช้อัลฟ่า:

+ (UIColor *) colorFromHexString:(NSString *)hexString alpha: (CGFloat)alpha{
    NSString *cleanString = [hexString stringByReplacingOccurrencesOfString:@"#" withString:@""];
    if([cleanString length] == 3) {
        cleanString = [NSString stringWithFormat:@"%@%@%@%@%@%@",
                       [cleanString substringWithRange:NSMakeRange(0, 1)],[cleanString substringWithRange:NSMakeRange(0, 1)],
                       [cleanString substringWithRange:NSMakeRange(1, 1)],[cleanString substringWithRange:NSMakeRange(1, 1)],
                       [cleanString substringWithRange:NSMakeRange(2, 1)],[cleanString substringWithRange:NSMakeRange(2, 1)]];
    }
    if([cleanString length] == 6) {
        cleanString = [cleanString stringByAppendingString:@"ff"];
    }

    unsigned int baseValue;
    [[NSScanner scannerWithString:cleanString] scanHexInt:&baseValue];

    float red = ((baseValue >> 24) & 0xFF)/255.0f;
    float green = ((baseValue >> 16) & 0xFF)/255.0f;
    float blue = ((baseValue >> 8) & 0xFF)/255.0f;

    return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
}

3

อัปเดตสำหรับ swift 1.2

class func colorWithHexString (hex:String) -> UIColor {
    var cString: NSString = hex.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()).uppercaseString

    if (cString.hasPrefix("#")) {
        cString = cString.substringFromIndex(1)
    }

    if (count(cString as String) != 6) {
        return UIColor.grayColor()
    }

    var rString: String = cString.substringToIndex(2)
    var gString: String = (cString.substringFromIndex(2) as NSString).substringToIndex(2)
    var bString: String = (cString.substringFromIndex(4) as NSString).substringToIndex(2)

    var r:CUnsignedInt = 0, g:CUnsignedInt = 0, b:CUnsignedInt = 0;
    NSScanner(string: rString).scanHexInt(&r)
    NSScanner(string: gString).scanHexInt(&g)
    NSScanner(string: bString).scanHexInt(&b)
    return UIColor(red: CGFloat(Float(r) / 255.0), green: CGFloat(Float(g) / 255.0), blue: CGFloat(Float(b) / 255.0), alpha: CGFloat(1))

}

3

สร้างส่วนขยายที่หรูหราสำหรับUIColor:

extension UIColor {

convenience init(string: String) {

        var uppercasedString = string.uppercased()
        uppercasedString.remove(at: string.startIndex)

        var rgbValue: UInt32 = 0
        Scanner(string: uppercasedString).scanHexInt32(&rgbValue)

        let red = CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0
        let green = CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0
        let blue = CGFloat(rgbValue & 0x0000FF) / 255.0

        self.init(red: red, green: green, blue: blue, alpha: 1)
    }
}

สร้างสีแดง:

let red = UIColor(string: "#ff0000") 

3
extension UIColor 
{
    class func fromHexaString(hex:String) -> UIColor
    {
        let scanner           = Scanner(string: hex)
        scanner.scanLocation  = 0
        var rgbValue: UInt64  = 0
        scanner.scanHexInt64(&rgbValue)

        return UIColor(
            red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
            green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
            blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
            alpha: CGFloat(1.0)
        )
    }
}

//you can call like this.

UIColor.fromHexaString(hex:3276b1)

2
 You Can Get UIColor From String Code Like
   circularSpinner.fillColor = [self getUIColorObjectFromHexString:@"27b8c8" alpha:9];

 //Function For Hex Color Use
    - (unsigned int)intFromHexString:(NSString *)hexStr
    {
        unsigned int hexInt = 0;

        // Create scanner
        NSScanner *scanner = [NSScanner scannerWithString:hexStr];

        // Tell scanner to skip the # character
        [scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"#"]];

        // Scan hex value
        [scanner scanHexInt:&hexInt];

        return hexInt;
    }




    - (UIColor *)getUIColorObjectFromHexString:(NSString *)hexStr alpha:(CGFloat)alpha
    {
        // Convert hex string to an integer
        unsigned int hexint = [self intFromHexString:hexStr];

        // Create color object, specifying alpha as well
        UIColor *color =
        [UIColor colorWithRed:((CGFloat) ((hexint & 0xFF0000) >> 16))/255
                        green:((CGFloat) ((hexint & 0xFF00) >> 8))/255
                         blue:((CGFloat) (hexint & 0xFF))/255
                        alpha:alpha];

        return color;
    }

    /Function For Hex Color Use
    - (unsigned int)intFromHexString:(NSString *)hexStr
    {
        unsigned int hexInt = 0;

        // Create scanner
        NSScanner *scanner = [NSScanner scannerWithString:hexStr];

        // Tell scanner to skip the # character
        [scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"#"]];

        // Scan hex value
        [scanner scanHexInt:&hexInt];

        return hexInt;
    }




    - (UIColor *)getUIColorObjectFromHexString:(NSString *)hexStr alpha:(CGFloat)alpha
    {
        // Convert hex string to an integer
        unsigned int hexint = [self intFromHexString:hexStr];

        // Create color object, specifying alpha as well
        UIColor *color =
        [UIColor colorWithRed:((CGFloat) ((hexint & 0xFF0000) >> 16))/255
                        green:((CGFloat) ((hexint & 0xFF00) >> 8))/255
                         blue:((CGFloat) (hexint & 0xFF))/255
                        alpha:alpha];

        return color;
    }

ถ้าคุณต้องการใช้รหัสนี้คุณก็จะเรียก [self getUIColorObjectFromHexString: @ "27b8c8" alpha: 9]; เท่านั้น ....
Manish Saini

2

ฉันต้องการให้แน่ใจว่าอัลฟานอกเหนือจากสีดังนั้นฉันเขียนหมวดหมู่ของตัวเอง

+ (UIColor *) colorWithHex:(int)color {

    float red = (color & 0xff000000) >> 24;
    float green = (color & 0x00ff0000) >> 16;
    float blue = (color & 0x0000ff00) >> 8;
    float alpha = (color & 0x000000ff);

    return [UIColor colorWithRed:red/255.0 green:green/255.0 blue:blue/255.0 alpha:alpha/255.0];
}

ใช้งานง่ายเช่นนี้

[UIColor colorWithHex:0xFF0000FF]; //Red
[UIColor colorWithHex:0x00FF00FF]; //Green
[UIColor colorWithHex:0x00FF00FF]; //Blue
[UIColor colorWithHex:0x0000007F]; //transparent black

2

ฉันสร้าง init สะดวกสบายสำหรับสิ่งนั้น:

extension UIColor {
convenience init(hex: String, alpha: CGFloat)
{
    let redH = CGFloat(strtoul(hex.substringToIndex(advance(hex.startIndex,2)), nil, 16))
    let greenH = CGFloat(strtoul(hex.substringWithRange(Range<String.Index>(start: advance(hex.startIndex, 2), end: advance(hex.startIndex, 4))), nil, 16))
    let blueH = CGFloat(strtoul(hex.substringFromIndex(advance(hex.startIndex,4)), nil, 16))

    self.init(red: redH/255, green: greenH/255, blue: blueH/255, alpha: alpha)
}
}

จากนั้นคุณสามารถสร้าง UIColor ได้ทุกที่ในโครงการของคุณเช่นนี้

UIColor(hex: "ffe3c8", alpha: 1)

หวังว่านี่จะช่วย ...


2

คุณสามารถสร้างคลาสส่วนขยายของ UIColor เป็น: -

ส่วนขยาย UIColor {

// MARK: - getColorFromHex / ** ฟังก์ชั่นนี้จะแปลงรหัส Hex ของสีเป็น RGB

- parameter color  hex string.

- returns: RGB color code.
*/
class func getColorFromHex(hexString:String)->UIColor{

    var rgbValue : UInt32 = 0
    let scanner:NSScanner =  NSScanner(string: hexString)

    scanner.scanLocation = 1
    scanner.scanHexInt(&rgbValue)

    return UIColor(red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0, green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0, blue: CGFloat(rgbValue & 0x0000FF) / 255.0, alpha: CGFloat(1.0))
}

}


2

สำหรับ swift 2.0+ รหัสนี้ใช้ได้กับฉัน

extension UIColor {
    /// UIColor(hexString: "#cc0000")
    internal convenience init?(hexString:String) {
        guard hexString.characters[hexString.startIndex] == Character("#") else {
            return nil
        }
        guard hexString.characters.count == "#000000".characters.count else {
            return nil
        }
        let digits = hexString.substringFromIndex(hexString.startIndex.advancedBy(1))
        guard Int(digits,radix:16) != nil else{
            return nil
        }
        let red = digits.substringToIndex(digits.startIndex.advancedBy(2))
        let green = digits.substringWithRange(Range<String.Index>(start: digits.startIndex.advancedBy(2),
            end: digits.startIndex.advancedBy(4)))
        let blue = digits.substringWithRange(Range<String.Index>(start:digits.startIndex.advancedBy(4),
            end:digits.startIndex.advancedBy(6)))
        let redf = CGFloat(Double(Int(red, radix:16)!) / 255.0)
        let greenf = CGFloat(Double(Int(green, radix:16)!) / 255.0)
        let bluef = CGFloat(Double(Int(blue, radix:16)!) / 255.0)
        self.init(red: redf, green: greenf, blue: bluef, alpha: CGFloat(1.0))
    }
}

รหัสนี้รวมถึงการตรวจสอบรูปแบบสตริง เช่น

let aColor = UIColor(hexString: "#dadada")!
let failed = UIColor(hexString: "123zzzz")

และเท่าที่ฉันรู้รหัสของฉันไม่มีข้อเสียสำหรับการรักษาความหมายของเงื่อนไขที่ล้มเหลวและส่งคืนค่าทางเลือก และนี่ควรเป็นคำตอบที่ดีที่สุด


2

โซลูชันรุ่นSwift 2.0ซึ่งจะจัดการค่าสีอัลฟาและการจัดการข้อผิดพลาดที่สมบูรณ์แบบอยู่ที่นี่:

func RGBColor(hexColorStr : String) -> UIColor?{

    var red:CGFloat = 0.0
    var green:CGFloat = 0.0
    var blue:CGFloat = 0.0
    var alpha:CGFloat = 1.0

    if hexColorStr.hasPrefix("#"){

        let index   = hexColorStr.startIndex.advancedBy(1)
        let hex     = hexColorStr.substringFromIndex(index)
        let scanner = NSScanner(string: hex)
        var hexValue: CUnsignedLongLong = 0

        if scanner.scanHexLongLong(&hexValue)
        {
            if hex.characters.count == 6
            {
                red   = CGFloat((hexValue & 0xFF0000) >> 16) / 255.0
                green = CGFloat((hexValue & 0x00FF00) >> 8)  / 255.0
                blue  = CGFloat(hexValue & 0x0000FF) / 255.0
            }
            else if hex.characters.count == 8
            {
                red   = CGFloat((hexValue & 0xFF000000) >> 24) / 255.0
                green = CGFloat((hexValue & 0x00FF0000) >> 16) / 255.0
                blue  = CGFloat((hexValue & 0x0000FF00) >> 8)  / 255.0
                alpha = CGFloat(hexValue & 0x000000FF)         / 255.0
            }
            else
            {
                print("invalid hex code string, length should be 7 or 9", terminator: "")
                return nil
            }
        }
        else
        {
            print("scan hex error")
       return nil
        }
    }

    let color: UIColor =  UIColor(red:CGFloat(red), green: CGFloat(green), blue:CGFloat(blue), alpha: alpha)
    return color
}

2
    //UIColorWithHexString

    static UIColor * UIColorWithHexString(NSString *hex) {
        unsigned int rgb = 0;
        [[NSScanner scannerWithString:
          [[hex uppercaseString] stringByTrimmingCharactersInSet:
           [[NSCharacterSet characterSetWithCharactersInString:@"0123456789ABCDEF"] invertedSet]]]
         scanHexInt:&rgb];
        return [UIColor colorWithRed:((CGFloat)((rgb & 0xFF0000) >> 16)) / 255.0
                               green:((CGFloat)((rgb & 0xFF00) >> 8)) / 255.0
                                blue:((CGFloat)(rgb & 0xFF)) / 255.0
                               alpha:1.0];
    }

การใช้

self.view.backgroundColor = UIColorWithHexString(@"#0F35C0");
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.