【问题标题】:How to segue smoothly from UITableViewController to UIViewController programmatically如何以编程方式从 UITableViewController 顺利切换到 UIViewController
【发布时间】:2020-04-29 03:04:51
【问题描述】:

我没有使用故事板,而是以编程方式完成所有工作。

所以我的问题是,当我尝试在我的手机上运行应用程序时(当我在 Xcode 中使用模拟器时不会发生这种情况),以及当我使用以下方法时......

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    let destinationVC = ThirdViewController()
    destinationVC.selectedExercise = exercises![indexPath.row]

    self.navigationController?.pushViewController(destinationVC, animated: true)
}

...从 UITableView 过渡到 UIView,View 的内容正常过渡,但是背景在过渡到 UIView 之前会冻结一秒钟。

是什么原因造成的,我该如何解决?

这是我要转换到的 viewController 的代码。

import UIKit
import RealmSwift

class ThirdViewController: UIViewController, UITextViewDelegate {

    let realm = try! Realm()

    var stats : Results<WeightSetsReps>?

    var weightTextField = UITextField()
    var weightLabel = UILabel()

    var notesTextView = UITextView()

    var repsTextField = UITextField()
    var repsLabel = UILabel()

    var timerImage = UIImageView()

    var nextSet = UIButton()
    var nextExcersise = UIButton()

    var selectedExercise : Exercises? {
        didSet{
            loadWsr()
        }
    }


    //MARK: - ViewDidLoad()
    override func viewDidLoad() {
        super.viewDidLoad()

        notesTextView.delegate = self

        timeClock()
        navConAcc()
        labelConfig()
        setTextFieldConstraints()
        setImageViewConstraints()
        setTextViewConstraints()
        setButtonConstraints()

        let tap = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
        view.addGestureRecognizer(tap)
    }


    //MARK: - UILabel
    func labelConfig(){
        weightTextField.placeholder = "Total weight..."
        weightTextField.layer.borderWidth = 1
        weightTextField.backgroundColor = .white
        weightTextField.layer.cornerRadius = 25
        weightTextField.layer.borderColor = UIColor.lightGray.cgColor

        weightLabel.text = "  Weight (lbs): "
        weightLabel.textColor = .black

        weightTextField.leftView = weightLabel
        weightTextField.leftViewMode = .always


        repsTextField.placeholder = "Number of Reps..."
        repsTextField.layer.borderWidth = 1
        repsTextField.backgroundColor = .white
        repsTextField.layer.cornerRadius = 25
        repsTextField.layer.borderColor = UIColor.lightGray.cgColor


        repsLabel.text = "  Repetitions: "
        repsLabel.textColor = .black

        notesTextView.layer.borderWidth = 1
        notesTextView.backgroundColor = .white
        notesTextView.layer.cornerRadius = 25
        notesTextView.layer.borderColor = UIColor.lightGray.cgColor
        notesTextView.text = "  Notes..."
        notesTextView.textColor = UIColor.lightGray
        notesTextView.returnKeyType = .done


        repsTextField.leftView = repsLabel
        repsTextField.leftViewMode = .always

        nextSet.layer.borderWidth = 1
        nextSet.backgroundColor = .white
        nextSet.layer.cornerRadius = 25
        nextSet.layer.borderColor = UIColor.lightGray.cgColor
        nextSet.setTitle("Next Set", for: .normal)
        nextSet.setTitleColor(.black, for: .normal)
        nextSet.addTarget(self, action: #selector(addNewSet), for: .touchUpInside)

        nextExcersise.layer.borderWidth = 1
        nextExcersise.backgroundColor = .white
        nextExcersise.layer.cornerRadius = 25
        nextExcersise.layer.borderColor = UIColor.lightGray.cgColor
        nextExcersise.setTitle("Next Exercise", for: .normal)
        nextExcersise.setTitleColor(.black, for: .normal)

        [weightTextField, repsTextField, notesTextView, nextSet, nextExcersise].forEach{view.addSubview($0)}
    }


    //MARK: - TextView Delegates
    func textViewDidBeginEditing(_ textView: UITextView) {
        if textView.text == "  Notes..." {
            textView.text = ""
            textView.textColor = UIColor.black
        }
    }

    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        if text == "\n" {
            textView.resignFirstResponder()
        }
        return true
    }

    func textViewDidEndEditing(_ textView: UITextView) {
        if textView.text == ""{
            notesTextView.text = "  Notes..."
            notesTextView.layer.borderColor = UIColor.lightGray.cgColor
        }
    }

    //MARK: - Dismiss Keyboard Function
    @objc func dismissKeyboard(){
        view.endEditing(true)
    }


    //MARK: - TextField Constraints
    func setTextFieldConstraints(){
        weightTextField.anchor(top: view.safeAreaLayoutGuide.topAnchor, leading: view.leadingAnchor, bottom: nil, trailing: view.trailingAnchor,padding: .init(top: 20, left: 40, bottom: 0, right: -40), size: .init(width: 0, height: 50))
        repsTextField.anchor(top: weightTextField.bottomAnchor, leading: view.leadingAnchor, bottom: nil, trailing: view.trailingAnchor, padding: .init(top: 30, left: 40, bottom: 0, right: -40) ,size: .init(width: 0, height: 50))
    }


    //MARK: - UIButton Functions
    @objc func addNewSet(){
        print("It Works")
    }

    //MARK: - UIButton Constraints
    func setButtonConstraints(){
        nextSet.anchor(top: nil, leading: view.leadingAnchor, bottom: view.safeAreaLayoutGuide.bottomAnchor, trailing: nil, padding: .init(top: 0, left: 40, bottom: 0, right: -150), size: .init(width: 120, height: 70))
        nextExcersise.anchor(top: nil, leading: nextSet.trailingAnchor, bottom: nextSet.bottomAnchor, trailing: view.trailingAnchor, padding: .init(top: 0, left: 85, bottom: 0, right: -40), size: .init(width: 120, height: 70))
       }


    //MARK: - ImageView Constraints
    func setImageViewConstraints(){
        timerImage.anchor(top: repsTextField.bottomAnchor, leading: view.leadingAnchor, bottom: nil, trailing: view.trailingAnchor, padding: .init(top: 40, left: 0, bottom: 0, right: 0), size: .init(width: 100, height: 100))
    }

    //MARK: - TextView Constraints
    func setTextViewConstraints(){
        notesTextView.anchor(top: timerImage.bottomAnchor, leading: view.leadingAnchor, bottom: nil, trailing: view.trailingAnchor, padding: .init(top: 40, left: 40, bottom: 0, right: -40), size: .init(width: 100, height: 110))
    }


    //MARK: - Navigation Bar Setup
    func navConAcc(){
        navigationItem.title = selectedExercise?.exerciseName
        navigationController?.navigationBar.prefersLargeTitles = true
    }

    //MARK: - Stopwatch
    func timeClock(){
        let image1 = UIImage(named: "stopwatch")
        timerImage = UIImageView(image: image1)
        timerImage.contentMode = .scaleAspectFit

        self.view.addSubview(timerImage)
    }

    //MARK: - Load Data
    func loadWsr() {
        stats = selectedExercise?.wsr.sorted(byKeyPath: "sets", ascending: true)
    }

    //MARK: - Save Data
    func save(wsr : WeightSetsReps){
        do {
            try realm.write {
                realm.add(wsr)
            }
        } catch {
            print("Error saving wsr data \(error)")
        }
    }

}

extension UIView {
    func anchor(top: NSLayoutYAxisAnchor?, leading: NSLayoutXAxisAnchor?, bottom: NSLayoutYAxisAnchor?, trailing: NSLayoutXAxisAnchor?, padding: UIEdgeInsets = .zero, size: CGSize = .zero){

        translatesAutoresizingMaskIntoConstraints = false

        if let top = top {
            topAnchor.constraint(equalTo: top, constant: padding.top).isActive = true
        }

        if let leading = leading {
            leadingAnchor.constraint(equalTo: leading, constant: padding.left).isActive = true
        }

        if let bottom = bottom {
            bottomAnchor.constraint(equalTo: bottom, constant: padding.bottom).isActive = true
        }

        if let trailing = trailing {
            trailingAnchor.constraint(equalTo: trailing, constant: padding.right).isActive = true
        }

        if size.width != 0 {
            widthAnchor.constraint(equalToConstant: size.width).isActive = true
        }

        if size.height != 0 {
            heightAnchor.constraint(equalToConstant: size.height).isActive = true
        }
    }
}

【问题讨论】:

  • 您是否尝试过在手机上运行时分析转换。直觉是您看到的延迟是 viewDidLoad 或 viewWillAppear 中的某些东西占用了太多时间并导致主线程被阻塞。
  • 这里是我的 viewDidLoad override func viewDidLoad() { super.viewDidLoad() notesTextView.delegate = self timeClock() navConAcc() labelConfig() setTextFieldConstraints() setImageViewConstraints() setTextViewConstraints() setButtonConstraints() let tap = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard)) view.addGestureRecognizer(tap) }
  • 编辑问题并将代码放在那里
  • 您需要配置文件——我们不知道所有这些功能的作用。如果您稍后或在后台可以执行任何操作,请将其移出 viewDidLoad
  • Google xcode 仪器时间分析器

标签: ios swift xcode uiview


【解决方案1】:

您没有正确实现编程视图控制器。以编程方式创建的视图控制器在loadView() 中构建其所有视图,而不是在viewDidLoad() 中。因此,在loadView() 中添加所有视图控制器的子视图(无需 调用super.loadView())。然后使用viewDidLoad() (with 调用super.viewDidLoad()) 进行查看后的工作,例如添加计时器、通知观察者等。我怀疑延迟是由错误配置的生命周期引起的。

看来您对 iOS 或 Swift 开发还比较陌生,因此我强烈建议您不要使用扩展,尤其是在 UIView 上进行自动布局。在开始扩展之前先了解它是如何工作的。程序化自动布局的流程是:

// adjust parameters first, like color, delegate, etc.
someView.translatesAutoresizingMaskIntoConstraints = false // set resizing to false before adding as a subview
view.addSubview(someView) // add as a subview
someView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16).isActive = true // add constraints

【讨论】:

  • 感谢您的建议,并尝试以这种方式进行设置,但无济于事,但我会继续搜索。关于我设置的扩展,我相信我的订单设置正确,不是吗?当你说我的订单有误时,你介意告诉我你指的是什么吗?是的,我对 iOS 和 Swift 还比较陌生,所以非常感谢您的帮助。
  • 那么问题不在于这个视图控制器。如果您已使用正确的生命周期对其进行了重构,并将所有内容剥离为裸机,但仍然存在故障,那么如果没有更多信息,我们谁也无法解决您的问题。至于扩展,去掉它;只需通常为每个子视图添加约束。如果您扩展了UIView 以使自动布局更容易,并且您在某处有if size.width != 0,那么您做的不对。不要犯学习太快的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-15
  • 2020-05-28
  • 2011-05-07
  • 2014-08-30
相关资源
最近更新 更多