Как мне упростить этот длинный код UIButton?

#ios #swift #xcode #uibutton

#iOS #swift #xcode #uibutton

Вопрос:

Я пытаюсь создать 5 UIButton (на самом деле 12, но код слишком длинный для публикации, поэтому я сократил до 5. Это все то же самое) и сделайте его угол круглым и добавьте тень

но я думаю, что есть лучший способ упростить этот длинный код

пожалуйста, помогите. Спасибо

класс ViewController: UIViewController {

 @IBOutlet weak var button: UIButton!
@IBOutlet weak var button2: UIButton!
@IBOutlet weak var button3: UIButton!
@IBOutlet weak var button4: UIButton!
@IBOutlet weak var button5: UIButton!

override func viewDidLoad() {
    super.viewDidLoad()
       
    button.layer.cornerRadius = 35
    button.layer.shadowRadius = 5
    button.layer.shadowColor = UIColor.black.cgColor
    button.layer.shadowOpacity = 0.5
    button.layer.shadowOffset = CGSize(width:0, height:1)
    button.layer.masksToBounds = false
    
    button2.layer.cornerRadius = 35
    button2.layer.shadowRadius = 5
    button2.layer.shadowColor = UIColor.black.cgColor
    button2.layer.shadowOpacity = 0.5
    button2.layer.shadowOffset = CGSize(width:0, height:1)
    button2.layer.masksToBounds = false
    
    button3.layer.cornerRadius = 35
    button3.layer.shadowRadius = 5
    button3.layer.shadowColor = UIColor.black.cgColor
    button3.layer.shadowOpacity = 0.5
    button3.layer.shadowOffset = CGSize(width:0, height:1)
    button3.layer.masksToBounds = false
    
    button4.layer.cornerRadius = 35
    button4.layer.shadowRadius = 5
    button4.layer.shadowColor = UIColor.black.cgColor
    button4.layer.shadowOpacity = 0.5
    button4.layer.shadowOffset = CGSize(width:0, height:1)
    button4.layer.masksToBounds = false
    
    button5.layer.cornerRadius = 35
    button5.layer.shadowRadius = 5
    button5.layer.shadowColor = UIColor.black.cgColor
    button5.layer.shadowOpacity = 0.5
    button5.layer.shadowOffset = CGSize(width:0, height:1)
    button5.layer.masksToBounds = false
  

Комментарии:

1. Почему бы просто не создать подкласс UIButton?

2. Я хотел бы узнать, как это сделать.

Ответ №1:

Создайте функцию для выполнения повторяющейся работы. Что-то вроде этого:

 @IBOutlet weak var button: UIButton!
@IBOutlet weak var button2: UIButton!
@IBOutlet weak var button3: UIButton!
@IBOutlet weak var button4: UIButton!
@IBOutlet weak var button5: UIButton!

//...
func configure(button: UIButton) {
    button.layer.cornerRadius = 35
    button.layer.shadowRadius = 5
    button.layer.shadowColor = UIColor.black.cgColor
    button.layer.shadowOpacity = 0.5
    button.layer.shadowOffset = CGSize(width:0, height:1)
    button.layer.masksToBounds = false
}

[button, button2, button3, button4, button5].forEach { configure(button:$0) }
  

Комментарии:

1. Работает как по волшебству! Спасибо. Xcode также сказал мне добавить { configure(button: $ 0) }, иначе он выдал ошибку. Теперь мой экран намного чище: D

2. Рад, что смог помочь. Да, я пропустил метку в параметре кнопки. Теперь вы должны найти функцию Array.forEach и потренироваться в ее использовании, пока не «получите ее». Это довольно полезно.

3. Другим улучшением, которое вы могли бы использовать, было бы IBOutletCollection . Это специальная форма IBOutlet, которая создает массив каждого объекта представления, который вы перетаскиваете в него в Interface Builder. Тогда вместо того, чтобы говорить [button, button2...] , что вы создадите IBOutletCollection с именем buttons, перетащите в него все свои кнопки, а затем просто скажите buttons.forEach{<code>}

4. вау, ваш метод и описание легко понять. Спасибо большое. Я попробую использовать Array.forEach и IBOutletCollection для дальнейшего понимания.

Ответ №2:

Вы можете просто использовать массивы

 [button1,button2..].forEach { button in
    button.layer.cornerRadius = 35
    button.layer.shadowRadius = 5
    button.layer.shadowColor = UIColor.black.cgColor
    button.layer.shadowOpacity = 0.5
    button.layer.shadowOffset = CGSize(width:0, height:1)
    button.layer.masksToBounds = false
}
  

или используйте методы, если вам нужно передавать разные параметры для разных кнопок

 setupButton(button1)
setupButton(button2)

func setupButton(_ button: UIButton) {
    button.layer.cornerRadius = 35
    button.layer.shadowRadius = 5
    button.layer.shadowColor = UIColor.black.cgColor
    button.layer.shadowOpacity = 0.5
    button.layer.shadowOffset = CGSize(width:0, height:1)
    button.layer.masksToBounds = false
}
  

Ответ №3:

это просто создать один метод и вызвать его

 [button,button2].forEach({self.createButton($0)})

func createButton(_ button: UIButton, radius: CGFloat = 35, shadowRadius: CGFloat = 5, shadowColor: UIColor = UIColor.black, shadowOpacity: Float = 0.5, shadowOffSet: CGSize = CGSize(width: 0, height: 1)){
    
    button.layer.cornerRadius = radius
    button.layer.shadowRadius = shadowRadius
    button.layer.shadowColor = shadowColor.cgColor
    button.layer.shadowOpacity = shadowOpacity
    button.layer.shadowOffset = shadowOffSet
    button.layer.masksToBounds = false
    
}
  

Комментарии:

1. Очень хорошее использование значений параметров по умолчанию. Это еще одна полезная техника для изучения. (проголосовал)

Ответ №4:

Вы всегда можете создать подкласс UIButton и создать свою собственную пользовательскую кнопку:

 class CustomButton: UIButton {
    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

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

    func setup() {
        layer.cornerRadius = 35
        layer.shadowRadius = 5
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOpacity = 0.5
        layer.shadowOffset = CGSize(width:0, height:1)
        layer.masksToBounds = false
    }
}

@IBOutlet weak var button: CustomButton!
@IBOutlet weak var button2: CustomButton!
@IBOutlet weak var button3: CustomButton!
@IBOutlet weak var button4: CustomButton!
@IBOutlet weak var button5: CustomButton!
  

Комментарии:

1. Обратите внимание, что ваш код не будет работать, если кнопка создана в раскадровке или XIB. (В этих случаях init(coder:) вызывается метод. Обычно я создаю общий setup() метод, который вызываю из обоих init(frame:) и init(coder:) . Таким образом, я могу вызывать свои объекты просмотра либо в коде, либо из раскадровки и получать одинаковое поведение (и мне не нужно поддерживать один и тот же код настройки в 2 местах.)

2. @DuncanC Вы на 100% правы, я делаю большинство своих представлений программно, так что просто небольшая оплошность по привычке. Я скоро обновлю свой ответ.

3. спасибо за другую перспективу. Я только начинаю кодировать, и сейчас это слишком сложно для меня XD

Ответ №5:

может быть, вы можете попробовать это в swift 5.3, используя переменные параметры

 @IBOutlet weak var button: UIButton!
@IBOutlet weak var button2: UIButton!
@IBOutlet weak var button3: UIButton!
@IBOutlet weak var button4: UIButton!
@IBOutlet weak var button5: UIButton!

//...
func configure(buttons: UIButton...) {
    for button in buttons {
        button.layer.cornerRadius = 35
        button.layer.shadowRadius = 5
        button.layer.shadowColor = UIColor.black.cgColor
        button.layer.shadowOpacity = 0.5
        button.layer.shadowOffset = CGSize(width:0, height:1)
        button.layer.masksToBounds = false
    }
}
configure(button, button1, button2, button3, button4, button5)