Swift: UIStackView UIControls с методом селектора, который не срабатывает - PullRequest
0 голосов
/ 03 ноября 2018

Введение

Я создаю приложение, которое использует пользовательское представление, в котором у меня есть UIStackView для сортировки 5 UIControls. Когда пользователь нажимает на один из UIControls, линия подчеркивания оживляется, скользя под повернутым UIControl.

Однако по какой-то причине метод / селектор для этих UIControls больше не вызывается. Я считаю, что это связано с тем, что я обновил свой Mac до обновления macOS (и Xcode), выпущенного на этой неделе (wk.44). (обновлено с swift 4.2 до swift 4.2.1). До обновления эта анимация и селектор работали отлично. Но я не уверен. И теперь я полностью застрял в том, что я делаю неправильно.

Context

  • Я создал игровую площадку и уменьшил все, насколько мог, и проблема не устранена.

  • Я пытался определить UIStackView в глобальной области видимости моего SetupView класса, но он ничего не меняет. Так что я полагаю, что это не проблема отмены стека или его подпредставлений?

  • Ниже я предоставил свой подкласс UIControl и мой SetupView (подкласс UIView), который я использую. Я создал игровую площадку, поэтому вы можете скопировать вставку на игровой площадке Xcode, чтобы проверить, если хотите.

Вопрос

  • Почему метод goalViewControlTapped(_ sender: SetupViewControl) не вызывается?

Код

import UIKit
import PlaygroundSupport

class SetupViewControl: UIControl {

    let titleLabel : UILabel = {
        let lbl = UILabel()
        lbl.font = UIFont(name: "Futura", size: 14)
        lbl.textColor = .white
        lbl.backgroundColor = .clear
        lbl.textAlignment = .center
        lbl.translatesAutoresizingMaskIntoConstraints = false
        return lbl
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupLabel()
        layer.cornerRadius = 5
    }

    fileprivate func setupLabel() {
        addSubview(titleLabel)
        titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 5).isActive = true
        titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -5).isActive = true
        titleLabel.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override var isHighlighted: Bool {
        didSet {
            UIView.animate(withDuration: 0.12) {
                self.backgroundColor = self.isHighlighted ? UIColor.lightGray : UIColor.clear
            }
        }
    }
}

class SetupView: UIView {

    let dataModel : [String] = ["2 weeks", "1 month", "2 months", "6 months", "1 year"]
    var selectionLineCenterX : NSLayoutConstraint!

    let selectionLine = UIView()
    let labelZero = SetupViewControl()
    let labelOne = SetupViewControl()
    let labelTwo = SetupViewControl()
    let labelThree = SetupViewControl()
    let labelFour = SetupViewControl()
    let labelFive = SetupViewControl()

    lazy var controlArray = [self.labelZero, self.labelOne, self.labelTwo, self.labelThree, self.labelFour, self.labelFive]

    init(frame: CGRect, color: UIColor) {
        super.init(frame: frame)
        self.backgroundColor = color
        setupView()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    fileprivate func setupView() {
        layer.cornerRadius = 0
        layer.borderColor = UIColor.black.cgColor
        layer.borderWidth = 1
        setupLabelText()
        setupControlsInStackView()
    }

    fileprivate func setupLabelText() {
        for num in 0...(dataModel.count - 1) {
            controlArray[num].titleLabel.text = dataModel[num]
        }
    }

    // let stackView = UIStackView(frame: .zero) I have tried to declare the stackView here but it doesn't fix my issue.
    func setupControlsInStackView() {
        var stackViewArray = [SetupViewControl]()
        for num in 0...(dataModel.count - 1) {
            controlArray[num].isUserInteractionEnabled = true
            controlArray[num].addTarget(self, action: #selector(goalViewControlTapped(_:)), for: .touchUpInside)
            stackViewArray.append(controlArray[num])
        }
        let stackView = UIStackView(arrangedSubviews: stackViewArray)
        stackView.alignment = .fill
        stackView.distribution = .fillEqually
        stackView.axis = .horizontal
        stackView.translatesAutoresizingMaskIntoConstraints = false
        addSubview(stackView)
        stackView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 8).isActive = true
        stackView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -8).isActive = true
        stackView.topAnchor.constraint(equalTo: topAnchor, constant: 15).isActive = true

        addSubview(selectionLine)
        selectionLine.backgroundColor = .white
        selectionLine.translatesAutoresizingMaskIntoConstraints = false
        selectionLine.heightAnchor.constraint(equalToConstant: 1).isActive = true
        selectionLine.topAnchor.constraint(equalTo: stackView.bottomAnchor).isActive = true
        selectionLine.widthAnchor.constraint(equalToConstant: 50).isActive = true
        selectionLineCenterX = selectionLine.centerXAnchor.constraint(equalTo: leadingAnchor, constant: -100)
        selectionLineCenterX.isActive = true
    }

    @objc fileprivate func goalViewControlTapped(_ sender: SetupViewControl) {
        print("This is not getting printed!!!")
        selectionLineCenterX.isActive = false
        selectionLineCenterX = selectionLine.centerXAnchor.constraint(equalTo: sender.centerXAnchor)
        selectionLineCenterX.isActive = true
        UIView.animate(withDuration: 0.25, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0.5, options: .curveEaseIn, animations: {
            self.layoutIfNeeded()
        }, completion: nil)
    }
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        let testView = SetupView(frame: .zero, color: UIColor.blue)
        view.addSubview(testView)
        testView.translatesAutoresizingMaskIntoConstraints = false
        testView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        testView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        testView.heightAnchor.constraint(equalToConstant: 100).isActive = true
        testView.widthAnchor.constraint(equalToConstant: 365).isActive = true
    }
}
// For live view in playground
let vc = ViewController()
vc.preferredContentSize = CGSize(width: 375, height: 812)
PlaygroundPage.current.liveView = vc

Спасибо, что прочитали мой вопрос.

1 Ответ

0 голосов
/ 03 ноября 2018

Показывает ли ваш UIStackView неоднозначное расположение при открытии отладчика представления? Если это так, это может привести к тому, что внутренние виды не получат сенсорные события.

Вы можете указать UIStackView:

x и y ограничения только

или

x, y, width и height.

В приведенном выше случае ограничение height отсутствует.

...