Я создаю приложение, использующее swift в последней версии Xcode 6, и хотел бы знать, как я могу изменить свою кнопку, чтобы она могла иметь закругленную границу, которую я мог бы при необходимости настроить. Как только это будет сделано, как я могу изменить цвет самой границы без добавления к ней фона? Другими словами, мне нужна слегка закругленная кнопка без фона, только граница 1pt определенного цвета.
Как сделать кнопку с округленной границей в Swift?
Ответ 1
Используйте button.layer.cornerRadius
, button.layer.borderColor
и button.layer.borderWidth
.
Обратите внимание, что для borderColor
требуется CGColor
, поэтому вы можете сказать (Swift 3/4):
button.backgroundColor = .clear
button.layer.cornerRadius = 5
button.layer.borderWidth = 1
button.layer.borderColor = UIColor.black.cgColor
Ответ 2
Сделать это задание в раскадровке (инспектор интерфейса Builder)
С помощью IBDesignable
мы можем добавить дополнительные параметры в Inspector Interface Builder для 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)
}
}
}
Затем просто установите атрибуты для кнопок на раскадровке.
Ответ 3
Я создал простую подструктуру 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, которое создает изображение из цвета, я нашел этот код здесь: fooobar.com/questions/43566/...
Он лучше всего работает, когда задан тип Custom в построителе интерфейса, поскольку тип системы по умолчанию слегка изменяет цвета при выделенной кнопке.
Ответ 4
Этот класс основан на всех комментариях и предложениях в ответах, а также может быть назначаемым непосредственно из xcode. Скопируйте в свой проект и вставьте любой UIButton и измените использование пользовательского класса, теперь просто выберите цвет границы или фона из 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
}
}
Ответ 5
Основываясь на ответе @returntrue, мне удалось реализовать его в Interface Builder.
Чтобы обойти угловые кнопки с помощью Interface Builder, добавьте ключ Path = "layer.cornerRadius"
с Type = "Number"
и Value = "10"
(или другое значение по мере необходимости) в "User Defined RunTime Attribute
" кнопки Identity Inspector
кнопки.
Ответ 6
Я думаю, что самый простой и чистый способ - использовать протокол, чтобы избежать наследования и повторения кода. Вы можете изменить эти свойства прямо из раскадровки
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 }
}
}
Обновить
В этой ссылке вы можете найти пример с утилитой Traceable protocol
Ответ 7
Вы можете использовать этот подкласс 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()
}
}
Ответ 8
@IBOutlet weak var yourButton: UIButton! {
didSet{
yourButton.backgroundColor = .clear
yourButton.layer.cornerRadius = 10
yourButton.layer.borderWidth = 2
yourButton.layer.borderColor = UIColor.white.cgColor
}
}
Ответ 9
@IBOutlet weak var button: UIButton!
...
Я думаю для радиуса как раз достаточно этого параметра:
button.layer.cornerRadius = 5
Ответ 10
в качестве подсказки, убедитесь, что ваша кнопка не является подклассом какого-либо пользовательского класса в раскадровке, в таком случае ваше место кода должно быть в пользовательском классе, так как сам код работает только из пользовательского класса, если ваша кнопка является подклассом по умолчанию Класс UIButton и его выход, надеюсь, это может помочь любому удивляться, почему угловые радиоприемники не применяются к моей кнопке из кода.
Ответ 11
Попробуйте эту кнопку границу с закругленными углами
anyButton.backgroundColor = .clear
anyButton.layer.cornerRadius = anyButton.frame.height / 2
anyButton.layer.borderWidth = 1
anyButton.layer.borderColor = UIColor.black.cgColor
Ответ 12
Вы можете UIButton
подкласс UIButton
и добавить к @IBInspectable
переменные @IBInspectable
чтобы настроить параметры пользовательских кнопок с помощью StoryBoard "Attribute Inspector". Ниже я записываю этот код.
@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
}
}
}