2017-09-09 2 views
2

J'essaye de reproduire la disposition d'IU de calculatrice d'Apple. Il s'agit d'un gif de ce que j'ai jusqu'ici.Essayer de donner un sens au comportement d'UILabel.

Les problèmes que je rencontre principalement concernent les UILables. Comme on le voit dans le gif ci-dessus, j'éprouve les problèmes suivants:

  • Lors de la rotation de l'appareil, les étiquettes pop « L1 » et « L2 », au lieu de la transition en douceur.

  • Les étiquettes des boutons de couleur marron disparaissent lors de la transition vers le mode portrait.

Pour les étiquettes « L1 » et « L2 » J'ai essayé d'expérimenter avec le mode de contenu et les contraintes, cependant, je reçois toujours des transitions maladroites. En ce qui concerne les étiquettes disparaissantes, au lieu de cacher/afficher la vue de la pile pour faire apparaître et disparaître la disposition via sa propriété cachée, j'ai plutôt essayé d'utiliser des contraintes sur la vue de la pile pour gérer la transition. le même.

J'ai également regardé en ligne et essayé quelques suggestions, cependant, la plupart des réponses étaient obsolètes ou n'ont tout simplement pas fonctionné.

Le code est très simple, il consiste principalement à paramétrer les vues et leurs contraintes.

extension UIStackView { 
    convenience init(axis: UILayoutConstraintAxis, distribution: UIStackViewDistribution = .fill) { 
     self.init() 
     self.axis = axis 
     self.distribution = distribution 
     self.translatesAutoresizingMaskIntoConstraints = false 
    } 
} 

class Example: UIView { 
    let mainStackView = UIStackView(axis: .vertical, distribution: .fill) 
    let subStackView = UIStackView(axis: .horizontal, distribution: .fillProportionally) 
    let portraitStackView = UIStackView(axis: .vertical, distribution: .fillEqually) 
    let landscapeStackView = UIStackView(axis: .vertical, distribution: .fillEqually) 

    var containerView: UIView = { 
     $0.backgroundColor = .darkGray 
     $0.translatesAutoresizingMaskIntoConstraints = false 
     return $0 
    }(UIView(frame: .zero)) 

    let mainView: UIView = { 
     $0.backgroundColor = .blue 
     $0.translatesAutoresizingMaskIntoConstraints = false 
     return $0 
    }(UIView(frame: .zero)) 

    let labelView: UIView = { 
     $0.backgroundColor = .red 
     $0.translatesAutoresizingMaskIntoConstraints = false 
     return $0 
    }(UIView(frame: .zero)) 

    var labelOne: UILabel! 
    var labelTwo: UILabel! 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
     backgroundColor = .red 
     autoresizingMask = [.flexibleWidth, .flexibleHeight] 

     labelOne = createLabel(text: "L1") 
     labelOne.translatesAutoresizingMaskIntoConstraints = false 
     labelOne.backgroundColor = .darkGray 
     labelTwo = createLabel(text: "L2") 
     labelTwo.translatesAutoresizingMaskIntoConstraints = false 
     labelTwo.backgroundColor = .black 

     landscapeStackView.isHidden = true 

     mainView.addSubview(labelView) 
     labelView.addSubview(labelOne) 
     labelView.addSubview(labelTwo) 
     addSubview(mainStackView) 
     mainStackView.addArrangedSubview(mainView) 

     setButtonStackView() 
     setStackViewConstriants() 
     setDisplayViewConstriants() 
    } 

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

    func setStackViewConstriants() { 
     mainStackView.translatesAutoresizingMaskIntoConstraints = false 
     mainStackView.topAnchor.constraint(equalTo: topAnchor).isActive = true 
     mainStackView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true 
     mainStackView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true 
     mainStackView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true 
    } 

    func setDisplayViewConstriants() { 
     mainView.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 288/667).isActive = true 

     labelView.heightAnchor.constraint(equalTo: mainView.heightAnchor, multiplier: 128/288).isActive = true 
     labelView.centerYAnchor.constraint(equalTo: mainView.centerYAnchor).isActive = true 
     labelView.leadingAnchor.constraint(equalTo: mainView.leadingAnchor, constant: 24).isActive = true 
     labelView.trailingAnchor.constraint(equalTo: mainView.trailingAnchor, constant: -24).isActive = true 

     labelOne.heightAnchor.constraint(equalTo: labelTwo.heightAnchor, multiplier: 88/32).isActive = true 
     labelOne.trailingAnchor.constraint(equalTo: labelView.trailingAnchor).isActive = true 
     labelOne.leadingAnchor.constraint(equalTo: labelView.leadingAnchor).isActive = true 
     labelOne.topAnchor.constraint(equalTo: labelView.topAnchor).isActive = true 

     labelTwo.topAnchor.constraint(equalTo: labelOne.bottomAnchor).isActive = true 
     labelTwo.trailingAnchor.constraint(equalTo: labelView.trailingAnchor).isActive = true 
     labelTwo.leadingAnchor.constraint(equalTo: labelOne.leadingAnchor).isActive = true 
     labelTwo.bottomAnchor.constraint(equalTo: labelView.bottomAnchor).isActive = true 
    } 

    func createLabel(text: String) -> UILabel { 
     let label = UILabel(frame: .zero) 
     label.text = text 
     label.font = UIFont.init(name: "Arial-BoldMT", size: 60) 
     label.textColor = .white 
     label.textAlignment = .right 
     label.contentMode = .right 
     label.minimumScaleFactor = 0.1 
     label.adjustsFontSizeToFitWidth = true 
     label.numberOfLines = 0 
     label.translatesAutoresizingMaskIntoConstraints = false 
     return label 
    } 

    func createButton(text: String) -> UIButton { 
     let button = UIButton(type: .custom) 
     button.setTitle(text, for: .normal) 
     button.setTitleColor(.white, for: .normal) 
     button.layer.borderColor = UIColor.white.cgColor 
     button.layer.borderWidth = 1 
     button.titleLabel?.font = UIFont.init(name: "Arial-BoldMT", size: 60) 
     button.titleLabel?.minimumScaleFactor = 0.1 
     button.titleLabel?.adjustsFontSizeToFitWidth = true 
     button.titleLabel?.translatesAutoresizingMaskIntoConstraints = false 
     button.titleLabel?.leadingAnchor.constraint(equalTo: button.leadingAnchor).isActive = true 
     button.titleLabel?.trailingAnchor.constraint(equalTo: button.trailingAnchor).isActive = true 
     button.titleLabel?.topAnchor.constraint(equalTo: button.topAnchor).isActive = true 
     button.titleLabel?.bottomAnchor.constraint(equalTo: button.bottomAnchor).isActive = true 
     button.titleLabel?.textAlignment = .center 
     button.titleLabel?.contentMode = .scaleAspectFill 
     button.titleLabel?.numberOfLines = 0 
     return button 
    } 

    func setButtonStackView() { 
     for _ in 1...5 { 
      let stackView = UIStackView(axis: .horizontal, distribution: .fillEqually) 
      for _ in 1...4 { 
       let button = createButton(text: "0") 
       button.backgroundColor = .brown 
       stackView.addArrangedSubview(button) 
      } 
      landscapeStackView.addArrangedSubview(stackView) 
     } 

     for _ in 1...5 { 
      let stackView = UIStackView(axis: .horizontal, distribution: .fillEqually) 
      for _ in 1...4 { 
       let button = createButton(text: "0") 
       button.backgroundColor = .purple 
       stackView.addArrangedSubview(button) 
      } 
      portraitStackView.addArrangedSubview(stackView) 
     } 

     subStackView.addArrangedSubview(landscapeStackView) 
     subStackView.addArrangedSubview(portraitStackView) 
     mainStackView.addArrangedSubview(subStackView) 
    } 

    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { 
     if UIDevice.current.orientation.isLandscape && landscapeStackView.isHidden == true { 
      self.landscapeStackView.isHidden = false 
     } 
     if UIDevice.current.orientation.isPortrait && landscapeStackView.isHidden == false { 
      self.landscapeStackView.isHidden = true 
     } 
     self.layoutIfNeeded() 
    } 
} 

Répondre

0

Vue d'ensemble:

  • Faites des choses progressivement avec les contrôleurs de composants séparés/vue (plus facile à déboguer)
  • La solution ci-dessous est seulement pour les étiquettes L1 et L2. Pour les boutons de la calculatrice, il est préférable d'utiliser un UICollectionViewController. (Je ne l'ai pas mis en œuvre, l'ajouter en tant que contrôleur de vue de l'enfant)

code:

private func setupLabels() { 

    view.backgroundColor = .red 

    let stackView   = UIStackView() 
    stackView.axis   = .vertical 
    stackView.alignment  = .fill 
    stackView.distribution = .fill 

    stackView.translatesAutoresizingMaskIntoConstraints = false 

    view.addSubview(stackView) 

    stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true 
    stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true 
    stackView.topAnchor.constraint(equalTo: view.topAnchor, constant: 20).isActive = true 


    let label1 = UILabel() 
    label1.text    = "L1" 
    label1.textColor  = .white 
    label1.backgroundColor = .darkGray 
    label1.textAlignment = .right 
    label1.font = UIFont.preferredFont(forTextStyle: .title1) 


    let label2 = UILabel() 
    label2.text    = "L2" 
    label2.textColor  = .white 
    label2.backgroundColor = .black 
    label2.textAlignment = .right 
    label2.font = UIFont.preferredFont(forTextStyle: .caption1) 

    stackView.addArrangedSubview(label1) 
    stackView.addArrangedSubview(label2) 
} 
+0

Comme je l'ai dit, ma principale préoccupation est le UILabels. J'ai déjà essayé d'ajouter les étiquettes dans une vue de pile, cependant, les résultats sont restés les mêmes. Ce projet est principalement à des fins d'apprentissage, c'est pourquoi j'utilise des vues de la pile – Biosx