আমি কীভাবে বোতামটি সুইফটে একটি বৃত্তাকার সীমানা রাখতে পারি?


232

আমি এক্সকোড 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
আমি এটি চেষ্টা করেছিলাম, তবে আমার একটি ছোট সমস্যা আছে প্রথম টেক্সটটি বর্ডার থেকেই শুরু হচ্ছে, সুতরাং এটির সমাধানের কোনও উপায় নেই এটি ভাল
দেখায় না

2
@ ভিনভাই 4 ইউ ব্যবহার করার চেষ্টা করুন titleEdgeInsets
সত্য

কীভাবে আমরা বোতামের বোতামের চেয়ে বড়টি তৈরি করতে পারি?
তাড়াতাড়ি

এটি উল্লেখ করতে বোতামটির জন্য একটি আউটলেট তৈরি করুন
জবস

আমি এটির মতো এটি ব্যবহার করতে চাই তবে কাজ করব না :( ইউআইবাটন.অ্যাপিয়ারেন্স () layer স্তরকর্নরেডিয়াস = 4
এমআর

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
এটি হামজা গাযৌনীর নীচের উত্তরের একটি অনুলিপি।
সত্য 20

আমি যখন বোর্ডার কলারের জন্য উপরের সমাধানটি ব্যবহার করি এটি ইন্টারফেস বিল্ডারে ব্যর্থ হয়, আমি নীচের কোডটি ব্যবহার করি তবে আমি সাফল্য পাই যদি আমি সেট এবং পাওয়ার চেয়ে ডেসেট ব্যবহার করি। @ আইবিআই স্পেসেবল ভেরার বর্ডার কালার: ইউআইসিওলর = .red did // ডিডসেট {// লেয়ার.বর্ডার কালার = বর্ডার কালার। = স্তর.বোর্ডার কালার অন্য {রিটার্ন শূন্য} রিটার্ন ইউআইক্লোর (সিজি কালার: রঙ)}}
আমর রাগান্বিত

1
বাহ, যাদুর মতো! ধন্যবাদ! গুগলারস - আপনি যে ফাইলটি রেখে দিচ্ছেন তাতে এই কোড স্নিপেটটি আপনার শেষ কোঁকড়া ধনুর্বন্ধকের বাইরে পুরোপুরি রেখে দেওয়া নিশ্চিত করুন - কোড স্নিপেট কোনও শ্রেণি বা ফাংশনের মধ্যে থাকা উচিত নয়
ভেলকুন

24

আমি একটি সাধারণ ইউআইবাটন সাবলকাস তৈরি করেছি যা 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)
}
}

এটি কোনও ইউআইআইমেজ এক্সটেনশন ব্যবহার করে যা কোনও রঙ থেকে একটি চিত্র তৈরি করে, আমি এখানে কোডটি পেয়েছি: https://stackoverflow.com/a/33675160

ডিফল্ট সিস্টেম টাইপ বোতামটি হাইলাইট করা হলে রংগুলিকে কিছুটা সংশোধন করে ইন্টারফেস বিল্ডারে কাস্টম টাইপ করার সময় এটি সর্বোত্তম কাজ করে।


13

এই শ্রেণিটি উত্তরে সমস্ত মন্তব্য এবং পরামর্শের উপর ভিত্তি করে এবং এক্সকোড থেকে সরাসরি নকশাযোগ্য হতে পারে। আপনার প্রকল্পে অনুলিপি করুন এবং কোনও ইউআইবাটন andোকান এবং কাস্টম শ্রেণি ব্যবহারের জন্য পরিবর্তন করুন, এখন কেবলমাত্র সাধারণ এবং / বা হাইলাইট হওয়া রাজ্যের জন্য এক্সকোড থেকে সীমানা বা পটভূমি রঙ নির্বাচন করুন।

//
//  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সত্যই যথেষ্ট হয়?
সত্য

@ রিটার্নট্রু হ্যাঁ আপনি ঠিক বলেছেন, ফাউন্ডেশন প্রয়োজন হয় না, আমি ভুল না হলে আমি মূল এক্সকোড বেসিক টেম্পলেট থেকে এসেছি। আমি কোড আপডেট করেছি।
le0diaz

কেবলমাত্র এটি হ'ল এটি সমস্ত সময় বোতামটি বিজ্ঞপ্তিযুক্ত করে তুলবে। এটিও ঠিক করতে আপনি কোণার ব্যাসার্ধের সম্পত্তি যুক্ত করতে পারেন।
Andreas777

10

@ রিটার্নট্রু উত্তরের ভিত্তিতে আমি এটিকে ইন্টারফেস বিল্ডারে প্রয়োগ করতে সক্ষম হয়েছি।

ইন্টারফেস বিল্ডার ব্যবহার করে বৃত্তাকার কোণার বোতামটি পেতে বোতামের " " এর Path = "layer.cornerRadius"সাথে একটি ( Type = "Number"এবং Value = "10"প্রয়োজনীয় হিসাবে অন্যান্য মান) যুক্ত করুন ।User Defined RunTime AttributeIdentity Inspector


1
এটি প্রকৃতপক্ষে কাজ করে তবে সুইফ্ট-নির্দিষ্ট নয়। প্রশ্নটি স্পষ্টভাবে জিজ্ঞাসা করে যে কীভাবে স্টিরিবোর্ড বা এ জাতীয় ব্যবহার না করে সুইফট ব্যবহার করে পছন্দসই প্রভাব অর্জন করতে হয়।
সত্য

2
আমার উত্তরটি ওপিকে নয় বরং অন্যান্য পাঠকদের কাছে নির্দেশিত হয়েছিল যারা আমার সমস্যার মুখোমুখি হয়েছিল। এবং কেবল এই পোস্টটি সন্ধান করেই সমস্যাটি সমাধান করতে সক্ষম হয়েছিল। আমার মতামত এবং অভিজ্ঞতায় উত্তরগুলি ওপি যা বলেছে ঠিক তার ঠিক উত্তর নেই, যতক্ষণ না তারা এর সাথে সম্পর্কিত হয় এবং অতিরিক্ত তথ্য দেয় যা পাঠকদের জন্য দরকারী। এই জাতীয় উত্তরগুলি ভোট দিয়ে আপনি দরকারী উত্তর নিরুৎসাহিত করবেন।
Zvi

1
যদিও এটি সাধারণত সত্য - বিশেষত বিস্তৃত প্রশ্নের জন্য - এই প্রশ্নটি এর চরিত্রটিতে পরিষ্কার। স্টোরিবোর্ডের মাধ্যমে একটি স্পষ্ট সমাধানের জন্য জিজ্ঞাসা করে এমন অনেকগুলি প্রশ্ন রয়েছে এবং যদি সম্ভব হয় তবে পাঠকরা স্টোরিবোর্ডকে ব্যবহার করে এমন কোনও সমাধান চান, তবে এই প্রশ্নগুলি দেখানোর জন্য গুগল অনুসন্ধান পদগুলিতে "স্টোরিবোর্ড" যুক্ত করা উচিত। আমি আপনার উত্তরটি খারাপ বলছি না, বরং ভুল জায়গায় করছি।
সত্য

যেহেতু আমি এই পোস্টটি আমার সমস্যার সমাধানের সবচেয়ে নিকটতম হিসাবে খুঁজে পেয়েছি, তাই আমি এটি এখানে পোস্ট করেছি। আপনার পথে যাওয়ার অর্থ হ'ল আমার একটি নতুন পোস্ট লেখা উচিত ছিল এবং আমার পোস্টটির উত্তর দেওয়া উচিত ছিল, যা মনে হয় আমার কাছে একটু ওভারকিল।
Zvi

1
আমি এই প্রশ্নগুলি খুঁজে পেয়েছি যা এগুলির চেয়ে আপনার সমস্যার সমাধান করার চেয়ে ভাল বলে মনে হচ্ছে: stackoverflow.com/questions/12301256 ; stackoverflow.com/questions/20477990
সত্য

6

আপনার প্রয়োজন অনুসারে ইউআইবাটনটি কাস্টমাইজ করতে আপনি ইউআইবাটনের এই সাবক্লাসটি ব্যবহার করতে পারেন।

রেফারেন্সের জন্য এই গিথুব রেপোটি দেখুন

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
হাই @ রিটার্নট্রু, আমি জানি না আপনি আমার উত্তরকে কেন নিম্নচোট করলেন ... আমি মনে করি আপনি এটি বুঝতে পারেন নি, আমি আপনাকে এই অধিবেশনটি দেখার জন্য আমন্ত্রণ জানিয়েছি: বিকাশকারী.অ্যাপল. com/ভিডিও / প্লে /wwdc2015/408 প্রোটোকল কেন ব্যবহার করছেন? প্রোটোকলটি আরও নমনীয়তা দেয়, আমার ডিফল্ট বাস্তবায়নও হতে পারে ইত্যাদি আমার উত্তরটি স্টোরিবোর্ডে এই বৈশিষ্ট্যগুলি সম্পাদনা করার অনুমতি দেয় এবং আমার কোডটি পুনরায় বা কোনও শ্রেণীর সাবক্লাস করার দরকার নেই আপনার উত্তরটি সঠিক তবে এখানে করার জন্য আমি অন্যভাবে ভাগ করেছি here এটি আপনি অন্য সমস্ত উত্তরকে হ্রাস করেছেন, আপনার মনে রাখা উচিত যে খ্যাতি অর্জনের আগে স্ট্যাকওভারফ্লো আমাদের জ্ঞান ভাগ করে নেওয়ার জন্য
হামজা

2
সঠিক, আপনার কোড আপনি তালিকাভুক্ত এই সমস্ত কিছুর অনুমতি দেয়। কিন্তু, ইউআইভিউ সমস্ত ইউআই উপাদানগুলির সুপারক্লাস হিসাবে, আপনার ইউআইভিউ এক্সটেনশনটি কাজটি করার পক্ষে যথেষ্ট। ট্রেসেবল প্রোটোকলটি কোনওভাবেই প্রয়োজন হয় না এবং কোনও উন্নতিও করে না (যেমন এটি কেবল ইউআইভিউতে অনুবাদ করে - কেবল ইউআইভিউ এবং তার উপক্লাসগুলি সন্ধানযোগ্য)।
সত্য

1
হাই @ রিটার্নট্রু, আপনি এই ব্যবহারের ক্ষেত্রে ঠিক বলেছেন, হতে পারে, আমাদের প্রোটোকলের প্রয়োজন নেই, তবে এটির সাথে আমাদের আরও নমনীয়তা রয়েছে এবং উদাহরণস্বরূপ, আমরা প্রয়োগের জন্য ডিফল্ট মানগুলি যুক্ত করতে পারি এবং কেবলমাত্র ইউআইআইমেজভিউ এবং ইউআইবুটন, আইয়ের জন্য উপলব্ধ I এই উত্তর দিয়ে আমার উত্তর আপডেট করবে :)
হামজা

1
কোণার ব্যাসার্ধ ওডার সীমানার রঙের মতো বৈশিষ্ট্যের জন্য ডিফল্ট মান প্রয়োগ করা সত্যিকার অর্থে বোধগম্য নয়। সেই মানগুলি আপনার ইউআইতে প্রতিটি দৃশ্যের জন্য পৃথকভাবে অর্থবহ উপায়ে প্রয়োগ করা উচিত ।
সত্য

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

পাশাপাশি সরু টিপসটি নিশ্চিত করুন যে আপনার বোতামটি স্টোরি বোর্ডের কোনও কাস্টম শ্রেণীর সাবক্লাস নয়, এমন ক্ষেত্রে আপনার কোডের সেরা স্থানটি কাস্টম শ্রেণিতে হওয়া উচিত এটির কারণ কারণ কোডটি কেবলমাত্র কাস্টম শ্রেণীর বাইরে কাজ করবে যদি আপনার বোতামটি ডিফল্টের সাবক্লাস থাকে ইউআইবাটন ক্লাস এবং এটির আউটলেট, আশা করি এটি কারও কাছ থেকে রেডিয়ো কোড থেকে আমার বোতামে প্রয়োগ করা হয় না কেন তা ভাবতে সহায়তা করতে পারে।


0
@IBOutlet weak var button: UIButton!

...

আমি ব্যাসার্ধের জন্য এই পরামিতিটি যথেষ্ট মনে করি:

button.layer.cornerRadius = 5

এটি নতুন কিছু যুক্ত করে না বলে মনে হয়।
সত্য

0

বৃত্তাকার কোণার সাথে এই বোতামের সীমানার চেষ্টা করুন

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ভেরিয়েবলগুলি যুক্ত করতে পারেন যাতে আপনি স্টোরিবোর্ড "অ্যাট্রিবিউট ইন্সপেক্টর" এর মাধ্যমে কাস্টম বোতামের পরামিতিগুলি কনফিগার করতে পারেন। নীচে আমি সেই কোডটি লিখি।

@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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.