मैं एक बटन कैसे बना सकता हूँ स्विफ्ट में एक गोल सीमा है?


232

मैं Xcode 6 के नवीनतम संस्करण में स्विफ्ट का उपयोग करके एक ऐप बना रहा हूं, और यह जानना चाहूंगा कि मैं अपने बटन को कैसे संशोधित कर सकता हूं ताकि इसमें एक गोल बॉर्डर हो सके जिसे मैं ज़रूरत पड़ने पर खुद को समायोजित कर सकूं। एक बार ऐसा हो जाने के बाद, मैं अपनी पृष्ठभूमि को जोड़े बिना सीमा का रंग कैसे बदल सकता हूं? दूसरे शब्दों में, मैं कोई पृष्ठभूमि के साथ थोड़ा गोल बटन चाहता हूं, केवल एक निश्चित रंग की 1pt सीमा।

जवाबों:


528

का उपयोग करें button.layer.cornerRadius, button.layer.borderColorऔर button.layer.borderWidth। ध्यान दें कि borderColorएक की आवश्यकता है CGColor, इसलिए आप कह सकते हैं (स्विफ्ट 3/4):

button.backgroundColor = .clear
button.layer.cornerRadius = 5
button.layer.borderWidth = 1
button.layer.borderColor = UIColor.black.cgColor

2
मैंने यह कोशिश की, लेकिन मुझे एक छोटी सी समस्या है जिसका पहला पाठ सीमा से ही शुरू हो रहा है, इसलिए इसकी अच्छी खोज यह हल करने का कोई तरीका नहीं है
vinbhai4u

2
@ vinbhai4u उपयोग करने का प्रयास करें titleEdgeInsets
वापसी सच

हम बटन टेक्स्ट से बॉक्स को बड़ा कैसे बना सकते हैं?
इतनी जल्दी

बटन को संदर्भित करने के लिए एक आउटलेट बनाएं
जॉब्स

मैं इसे इस तरह से उपयोग करना चाहता हूं लेकिन काम नहीं करता :( UIButton.appearance ()। layer.cornerRadius = 4
MR

65

स्टोरीबोर्ड में यह काम करने के लिए (इंटरफ़ेस बिल्डर इंस्पेक्टर)

इसकी मदद से IBDesignable, हम इंटरफ़ेस बिल्डर इंस्पेक्टर के लिए UIButtonऔर विकल्प जोड़ सकते हैं और उन्हें स्टोरीबोर्ड पर ट्विक कर सकते हैं। सबसे पहले, अपने प्रोजेक्ट में निम्न कोड जोड़ें।

@IBDesignable extension UIButton {

    @IBInspectable var borderWidth: CGFloat {
        set {
            layer.borderWidth = newValue
        }
        get {
            return layer.borderWidth
        }
    }

    @IBInspectable var cornerRadius: CGFloat {
        set {
            layer.cornerRadius = newValue
        }
        get {
            return layer.cornerRadius
        }
    }

    @IBInspectable var borderColor: UIColor? {
        set {
            guard let uiColor = newValue else { return }
            layer.borderColor = uiColor.cgColor
        }
        get {
            guard let color = layer.borderColor else { return nil }
            return UIColor(cgColor: color)
        }
    }
}

फिर बस स्टोरीबोर्ड पर बटन के लिए विशेषताओं को सेट करें।

यहां छवि विवरण दर्ज करें


4
यह कमोबेश हमज़ा ग़ज़ौनी के जवाब की एक प्रति है।
वापसी सच

जब मैं ऊपर दिए गए समाधान का उपयोग बोर्डरक्लर के लिए करता हूं तो इसका निर्माण इंटरफेसबिल्डर में विफल हो जाता है, मैं नीचे दिए गए कोड का उपयोग करता हूं, लेकिन अगर मैं सेट और प्राप्त करने के बजाय आईसेट का उपयोग करता हूं तो मुझे सफलता मिलती है। @IBInspectable var borderColor: UIColor = .red {// didSet {// layer.borderColor = borderColor.cgColor //} सेट {guard let uiColor = newValue वरना {return - layer.borderColor = uiColor.cgColor} को {guard let रंग दें = layer.borderColor वरना {वापसी nil} वापसी UIColor (cgColor: color)}}
अमृत ​​गुस्सा

1
वाह, जादू की तरह! धन्यवाद! Googler - सुनिश्चित करें कि यह कोड स्निपेट पूरी तरह से आपके पिछले अंतिम घुंघराले ब्रेस के बाहर है जिसे आप इसमें डाल रहे हैं - कोड स्निपेट किसी भी वर्ग या फ़ंक्शन के अंदर नहीं होना चाहिए
वेलकुन

24

मैंने एक साधारण UIButton उपवर्ग बनाया है जो tintColorअपने पाठ और बॉर्डर रंगों के लिए उपयोग करता है और जब हाइलाइट किया जाता है तो इसकी पृष्ठभूमि बदल जाती है tintColor

class BorderedButton: UIButton {

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    layer.borderWidth = 1.0
    layer.borderColor = tintColor.CGColor
    layer.cornerRadius = 5.0
    clipsToBounds = true
    contentEdgeInsets = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
    setTitleColor(tintColor, forState: .Normal)
    setTitleColor(UIColor.whiteColor(), forState: .Highlighted)
    setBackgroundImage(UIImage(color: tintColor), forState: .Highlighted)
}
}

यह एक UIImage एक्सटेंशन का उपयोग करता है जो एक रंग से एक छवि बनाता है, मुझे वह कोड यहां मिला: https://stackoverflow.com/a/33675160

इंटरफ़ेस बिल्डर में कस्टम टाइप करने के लिए यह सबसे अच्छा काम करता है क्योंकि बटन के हाइलाइट होने पर डिफ़ॉल्ट सिस्टम टाइप रंगों को थोड़ा संशोधित करता है।


13

यह वर्ग सभी टिप्पणियों और उत्तरों में सुझावों पर आधारित है, और सीधे xcode से भी डिजाइन किया जा सकता है। अपनी परियोजना में कॉपी करें और किसी भी यूआईबूटन को डालें और कस्टम वर्ग का उपयोग करने के लिए बदलें, अब सामान्य और / या हाइलाइट किए गए राज्यों के लिए बसकोड से सीमा या पृष्ठभूमि का रंग चुनें।

//
//  RoundedButton.swift
//

import UIKit

@IBDesignable
class RoundedButton:UIButton {

    @IBInspectable var borderWidth: CGFloat = 0 {
        didSet {
            layer.borderWidth = borderWidth
        }
    }
    //Normal state bg and border
    @IBInspectable var normalBorderColor: UIColor? {
        didSet {
            layer.borderColor = normalBorderColor?.CGColor
        }
    }

    @IBInspectable var normalBackgroundColor: UIColor? {
        didSet {
            setBgColorForState(normalBackgroundColor, forState: .Normal)
        }
    }


    //Highlighted state bg and border
    @IBInspectable var highlightedBorderColor: UIColor?

    @IBInspectable var highlightedBackgroundColor: UIColor? {
        didSet {
            setBgColorForState(highlightedBackgroundColor, forState: .Highlighted)
        }
    }


    private func setBgColorForState(color: UIColor?, forState: UIControlState){
        if color != nil {
            setBackgroundImage(UIImage.imageWithColor(color!), forState: forState)

        } else {
            setBackgroundImage(nil, forState: forState)
        }
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        layer.cornerRadius = layer.frame.height / 2
        clipsToBounds = true

        if borderWidth > 0 {
            if state == .Normal && !CGColorEqualToColor(layer.borderColor, normalBorderColor?.CGColor) {
                layer.borderColor = normalBorderColor?.CGColor
            } else if state == .Highlighted && highlightedBorderColor != nil{
                layer.borderColor = highlightedBorderColor!.CGColor
            }
        }
    }

}

//Extension Required by RoundedButton to create UIImage from UIColor
extension UIImage {
    class func imageWithColor(color: UIColor) -> UIImage {
        let rect: CGRect = CGRectMake(0, 0, 1, 1)
        UIGraphicsBeginImageContextWithOptions(CGSizeMake(1, 1), false, 1.0)
        color.setFill()
        UIRectFill(rect)
        let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}

1
आयात करना क्यों Foundationजब UIKitवास्तव में आयात करता है?
सच्चे

@returntrue हां आप सही हैं, फाउंडेशन की आवश्यकता नहीं है, मैं मूल xcode बुनियादी टेम्पलेट से आया हूं अगर मैं गलत नहीं हूं। मैंने कोड अपडेट किया।
leddiaz

केवल एक चीज यह है कि यह हर समय बटन को परिपत्र बना देगा। हो सकता है कि आप इसे ठीक करने के लिए एक कोने की त्रिज्या संपत्ति जोड़ सकते हैं।
एंड्रियास 77

10

@Returntrue उत्तर के आधार पर मैं इसे इंटरफ़ेस बिल्डर में लागू करने में कामयाब रहा।

इंटरफ़ेस बिल्डर एक कुंजी जोड़ने का उपयोग कर दौर कोनों बटन प्राप्त करने के लिए Path = "layer.cornerRadius"के साथ Type = "Number"और Value = "10""में (या अन्य मूल्य के रूप में) की आवश्यकता User Defined RunTime Attribute" के Identity Inspectorबटन की।


1
यह वास्तव में काम करता है, लेकिन स्विफ्ट-विशिष्ट नहीं है। प्रश्न स्पष्ट रूप से पूछता है कि स्विफ्ट का उपयोग करके वांछित प्रभाव कैसे प्राप्त किया जाए, स्टोरीबोर्ड या इस तरह का उपयोग करके नहीं।
असली

2
मेरा उत्तर ओपी को नहीं बल्कि अन्य पाठकों को निर्देशित किया गया था जिन्होंने मेरी समस्या का सामना किया। और केवल इस पोस्ट को खोजने से समस्या को हल करने में सक्षम थे। मेरी राय और अनुभव में, ओपी ने जो पूछा, जब तक वे उससे संबंधित हैं और अतिरिक्त जानकारी नहीं देते हैं, जो पाठकों के लिए उपयोगी हैं, तो उत्तर बिल्कुल नहीं हैं। इस तरह के उत्तरों को नीचे रखकर आप उपयोगी उत्तरों को हतोत्साहित करते हैं।
ज़वी

1
हालांकि यह आम तौर पर सच है - विशेष रूप से व्यापक प्रश्नों के लिए - यह बहुत ही प्रश्न इसके चरित्र में स्पष्ट है। ऐसे प्रश्नों की एक भीड़ मौजूद है जो स्टोरीबोर्ड के माध्यम से एक स्पष्ट समाधान के लिए पूछते हैं, और यदि संभव हो तो पाठकों के पास एक ऐसा समाधान होना चाहिए जो स्टोरीबोर्ड का उपयोग करता है, तो इन सवालों को दिखाने के लिए Google खोज शब्दों में "स्टोरीबोर्ड" को जोड़ना पर्याप्त है। मैं यह नहीं कह रहा हूं कि आपका उत्तर बुरा है, बल्कि गलत जगह है।
वापसी सच

चूँकि मैंने इस पोस्ट को अपनी समस्या को दूर करने के लिए निकटतम पाया, इसलिए मैंने इसे यहाँ पोस्ट किया। आपका रास्ता तय करने का मतलब है कि मुझे एक नई पोस्ट लिखनी चाहिए और मेरी पोस्ट का जवाब देना चाहिए, जो मुझे लगता है, थोड़ा ओवरकिल है।
ज़वी

1
मैंने उन प्रश्नों को पाया है जो आपकी समस्या को इस से बेहतर बताते हैं: stackoverflow.com/questions/12301256 ; stackoverflow.com/questions/20477990
सच

6

आप UIButton के इस उपवर्ग का उपयोग अपनी आवश्यकताओं के अनुसार UIButton को अनुकूलित करने के लिए कर सकते हैं।

संदर्भ के लिए इस github रेपो पर जाएँ

class RoundedRectButton: UIButton {

    var selectedState: Bool = false

    override func awakeFromNib() {
        super.awakeFromNib()
        layer.borderWidth = 2 / UIScreen.main.nativeScale
        layer.borderColor = UIColor.white.cgColor
        contentEdgeInsets = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
    }


    override func layoutSubviews(){
        super.layoutSubviews()
        layer.cornerRadius = frame.height / 2
        backgroundColor = selectedState ? UIColor.white : UIColor.clear
        self.titleLabel?.textColor = selectedState ? UIColor.green : UIColor.white
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        selectedState = !selectedState
        self.layoutSubviews()
    }
}

जिसने भी इसको उतारा है, क्या आपने भी इस तरह से काम करने की कोशिश की ??? बस अपना समय बर्बाद न करें
निकेश झा

एक डाउनवोट क्यों? यह काम करने लगता है और बहुत साफ है।
शीतगृह 1384

@ कोल्डगर्ब 1384 बिल्कुल :)
निकेश झा

3

मुझे लगता है कि सबसे आसान और सबसे साफ तरीका है, विरासत और कोड की पुनरावृत्ति से बचने के लिए प्रोटोकॉल का उपयोग करना। आप इस गुण को सीधे स्टोरीबोर्ड से बदल सकते हैं

protocol Traceable {
    var cornerRadius: CGFloat { get set }
    var borderColor: UIColor? { get set }
    var borderWidth: CGFloat { get set }
}

extension UIView: Traceable {

    @IBInspectable var cornerRadius: CGFloat {
        get { return layer.cornerRadius }
        set {
            layer.masksToBounds = true
            layer.cornerRadius = newValue
        }
    }

    @IBInspectable var borderColor: UIColor? {
        get {
            guard let cgColor = layer.borderColor else { return nil }
            return  UIColor(cgColor: cgColor)
        }
        set { layer.borderColor = newValue?.cgColor }
    }

    @IBInspectable var borderWidth: CGFloat {
        get { return layer.borderWidth }
        set { layer.borderWidth = newValue }
    }
}

अपडेट करें

इस लिंक में आप ट्रेस करने योग्य प्रोटोकॉल की उपयोगिता के साथ एक उदाहरण पा सकते हैं

यहां छवि विवरण दर्ज करें


2
आपको वास्तव में यहां प्रोटोकॉल की आवश्यकता नहीं है। इसके बिना पूरी तरह से ठीक काम करता है।
सच्चे

2
हाय @returntrue, मुझे नहीं पता कि आप मेरे जवाब को क्यों कम कर रहे हैं ... मुझे लगता है कि आप इसे समझ नहीं पाए थे, मैं आपको इस सत्र को देखने के लिए आमंत्रित करता हूं: developer.apple.com/videos/play/wwdc2015/408 प्रोटोकॉल का उपयोग क्यों कर रहे हैं? प्रोटोकॉल अधिक लचीलेपन की अनुमति देता है, मेरे पास डिफ़ॉल्ट कार्यान्वयन हो सकता है, आदि मेरा उत्तर स्टोरीबोर्ड में इस गुणों को संपादित करने की अनुमति देता है, और मुझे कोड को दोहराने या किसी भी वर्ग को उप-वर्ग करने की आवश्यकता नहीं है आपका उत्तर सही है लेकिन यहां मैंने एक और तरीका साझा किया है यह आप अन्य सभी उत्तरों को छोड़ देते हैं, आपको यह याद रखना चाहिए कि स्टैकओवरफ़्लो प्रतिष्ठा अर्जित करने से पहले हमारे जानकारों को साझा करने के लिए है
हमजा

2
सही, आपका कोड आपके द्वारा सूचीबद्ध इन सभी चीजों की अनुमति देता है। लेकिन, यूआईवीवाई सभी यूआई तत्वों का सुपरक्लास है, आपका यूआईवीवाई विस्तार काम करने के लिए पर्याप्त है। किसी भी तरह से प्रोटोकॉल ट्रैसेबल की आवश्यकता नहीं होती है और इसमें कोई सुधार नहीं होता है (क्योंकि यह केवल यूआईवीवाईई में अनुवाद करता है - केवल यूआईवीयूवाई और इसके उपवर्ग ट्रेस करने योग्य हैं)।
सच्चे

1
hi @returntrue, आप इस उपयोग के मामले में सही हैं, हमें प्रोटोकॉल की आवश्यकता नहीं है, लेकिन इसके साथ हमारे पास अधिक लचीलापन है, और उदाहरण के लिए, हम लागू करने के लिए डिफ़ॉल्ट मान जोड़ सकते हैं और केवल UIImageView और UIButton, I के लिए उपलब्ध हैं इस उदाहरण के साथ मेरे जवाब को अपडेट करूंगा :)
हमजा

1
कोने रेडियस ओडर बॉर्डर रंग जैसे गुणों के लिए डिफ़ॉल्ट मानों को लागू करने के लिए यह वास्तव में समझ में नहीं आता है। उन मानों को आपके UI में प्रत्येक दृश्य उदाहरण के लिए अलग-अलग अर्थपूर्ण तरीके से लागू किया जाना चाहिए ।
वापसी सच

3
   @IBOutlet weak var yourButton: UIButton! {
        didSet{
            yourButton.backgroundColor = .clear
            yourButton.layer.cornerRadius = 10
            yourButton.layer.borderWidth = 2
            yourButton.layer.borderColor = UIColor.white.cgColor
        }
    }

1

जैसा कि टिप टिप यह सुनिश्चित करता है कि आपका बटन कहानी बोर्ड में किसी भी कस्टम वर्ग का उपवर्ग नहीं है, ऐसे में आपका कोड सबसे अच्छी जगह कस्टम वर्ग में होना चाहिए, यह स्व कारण कोड कस्टम वर्ग से बाहर काम करता है यदि आपका बटन डिफ़ॉल्ट का उपवर्ग है UIButton वर्ग और इसके आउटलेट, आशा करते हैं कि यह किसी को भी आश्चर्य में डाल सकता है कि कॉर्नर रेडियो कोड से मेरे बटन पर क्यों लागू नहीं होता है।


0
@IBOutlet weak var button: UIButton!

...

मुझे लगता है कि त्रिज्या के लिए बस यह पैरामीटर पर्याप्त है:

button.layer.cornerRadius = 5

यह कुछ नया नहीं जोड़ता है, ऐसा लगता है।
असली सच

0

गोल कोनों के साथ TRY इस बटन की सीमा

anyButton.backgroundColor = .clear

anyButton.layer.cornerRadius = anyButton.frame.height / 2

anyButton.layer.borderWidth = 1

anyButton.layer.borderColor = UIColor.black.cgColor

हाँ, लेकिन यह एक कोनेरेडियस का उपयोग करने के विचार का परिचय देता है जो गतिशील है, मुझे नहीं लगता कि यह केवल कॉपी-एंड-पेस्ट किया गया था।
बेनकाक

0
import UIKit

@IBDesignable
class RoundedButton: UIButton {
    
    @IBInspectable var cornerRadius: CGFloat = 8
    @IBInspectable var borderColor: UIColor? = .lightGray
    
    override func draw(_ rect: CGRect) {
        layer.cornerRadius = cornerRadius
        layer.masksToBounds = true
        layer.borderWidth = 1
        layer.borderColor = borderColor?.cgColor
        
    }
    
    
}

-1

आप इसमें उप-वर्ग UIButtonजोड़ सकते हैं और @IBInspectableचर जोड़ सकते हैं ताकि आप StoryBoard "गुण निरीक्षक" के माध्यम से कस्टम बटन मापदंडों को कॉन्फ़िगर कर सकें। नीचे मैं उस कोड को लिखता हूं।

@IBDesignable
class BHButton: UIButton {

    /*
    // Only override draw() if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func draw(_ rect: CGRect) {
        // Drawing code
    }
    */

    @IBInspectable lazy var isRoundRectButton : Bool = false

    @IBInspectable public var cornerRadius : CGFloat = 0.0 {
        didSet{
            setUpView()
        }
    }

    @IBInspectable public var borderColor : UIColor = UIColor.clear {
        didSet {
            self.layer.borderColor = borderColor.cgColor
        }
    }

    @IBInspectable public var borderWidth : CGFloat = 0.0 {
        didSet {
            self.layer.borderWidth = borderWidth
        }
    }

    //  MARK:   Awake From Nib

    override func awakeFromNib() {
        super.awakeFromNib()
        setUpView()
    }

    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        setUpView()
    }

    func setUpView() {
        if isRoundRectButton {
            self.layer.cornerRadius = self.bounds.height/2;
            self.clipsToBounds = true
        }
        else{
            self.layer.cornerRadius = self.cornerRadius;
            self.clipsToBounds = true
        }
    }

}

-1

मुझे लगता है कि यह सरल रूप है

        Button1.layer.cornerRadius = 10(Half of the length and width)
        Button1.layer.borderWidth = 2
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.