จะใช้สีเส้นขอบไล่ระดับสีกับ UIButton ได้อย่างไร

ฉันต้องการที่จะบรรลุสิ่งนี้ ฉันได้ค้นหาสิ่งนี้ ฉันได้รับคำแนะนำว่าฉันสามารถวางมุมมองแบบไล่ระดับสีไว้ด้านหลังปุ่มโดยมีความสูงและความกว้างมากกว่าปุ่มได้ แต่ฉันต้องการรัศมีมุมและสีเส้นขอบที่แน่นอนพร้อมการไล่ระดับสี

ภาพตัวอย่าง


person Aalok verma    schedule 02.11.2019    source แหล่งที่มา
comment
คุณดูคำตอบนี้แล้วหรือยัง? stackoverflow.com/a/36836787   -  person Hima    schedule 02.11.2019


คำตอบ (1)


คุณสามารถสร้างคลาสย่อย BorderedButton ของคุณเองได้ซึ่งจะ:

  • เพิ่มเลเยอร์ย่อยไล่ระดับสี
  • สร้างเลเยอร์รูปร่างซึ่งประกอบด้วยเส้นทางของเส้นขอบ และ
  • ใช้เลเยอร์รูปร่างนั้นเป็นมาสก์ให้กับเลเยอร์ไล่ระดับสีเพื่อสร้างเส้นขอบไล่ระดับสีตามรูปร่างของเส้นทาง

E.g.:

@IBDesignable
class BorderedButton: UIButton {
    @IBInspectable var lineWidth:    CGFloat = 3  { didSet { setNeedsLayout() } }
    @IBInspectable var cornerRadius: CGFloat = 10 { didSet { setNeedsLayout() } }

    let borderLayer: CAGradientLayer = {
        let borderLayer = CAGradientLayer()
        borderLayer.type = .axial
        borderLayer.colors = [#colorLiteral(red: 0.6135130525, green: 0.3031745553, blue: 0.9506058097, alpha: 1).cgColor, #colorLiteral(red: 0.9306473136, green: 0.1160953864, blue: 0.8244602084, alpha: 1).cgColor]
        borderLayer.startPoint = CGPoint(x: 0, y: 1)
        borderLayer.endPoint = CGPoint(x: 1, y: 0)
        return borderLayer
    }()

    override init(frame: CGRect = .zero) {
        super.init(frame: frame)
        configure()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        configure()
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        borderLayer.frame = bounds

        let mask = CAShapeLayer()
        let rect = bounds.insetBy(dx: lineWidth / 2, dy: lineWidth / 2)
        mask.path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).cgPath
        mask.lineWidth = lineWidth
        mask.fillColor = UIColor.clear.cgColor
        mask.strokeColor = UIColor.white.cgColor
        borderLayer.mask = mask
    }
}

private extension BorderedButton {
    func configure() {
        layer.addSublayer(borderLayer)
    }
}

โปรดทราบว่า:

  • ฉันอัปเดต frame ของเลเยอร์ไล่ระดับสีและเส้นทางที่ใช้เป็น mask ภายในเมธอด layoutSubviews ซึ่งช่วยให้มั่นใจได้ว่าเส้นขอบจะแสดงผลอย่างถูกต้องหากขนาดเปลี่ยนแปลง (เช่น คุณใช้ข้อจำกัดในการกำหนดขนาดของมุมมอง)
  • ฉันได้สร้างสิ่งนี้ @IBDesignable เพื่อให้คุณสามารถเพิ่มสิ่งนี้ลงในกระดานเรื่องราวได้ และคุณจะเห็นว่ามันแสดงผลอย่างถูกต้อง
  • ฉันได้สร้าง cornerRadius และ lineWidth ให้เป็น @IBInspectable เพื่อให้คุณสามารถปรับสิ่งเหล่านี้ใน IB ได้ (และเนื่องจากพวกเขามีผู้สังเกตการณ์ didSet คนที่ตั้งค่า "ต้องการเลย์เอาต์" พวกเขาจะคอยดูแลให้สังเกตการเปลี่ยนแปลงได้ในกระดานเรื่องราว)

อย่างไรก็ตามนั่นทำให้:

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

person Rob    schedule 02.11.2019