2017-08-28 20 views
0

我正在創建自己的自定義分段控制器。我正在關注這個視頻(https://www.youtube.com/watch?v=xGdRCUrSu94)。這是自定義組件的代碼:爲什麼這個UIView的寬度比故事板長?

// 
// YearSelectorSegControl.swift 
// OurDailyStrength iOS 
// 
// Created by Rob Avery on 8/28/17. 
// Copyright © 2017 Rob Avery. All rights reserved. 
// 

import UIKit 

@IBDesignable 
class YearSelectorSegControl: UIView { 

    var buttons = [UIButton]() 
    var selector: UIView! 
    var sv: UIStackView! 

    @IBInspectable 
    var borderWidth: CGFloat = 0 { 
     didSet { 
      layer.borderWidth = borderWidth 
     } 
    } 

    @IBInspectable 
    var borderColor: UIColor = UIColor.clear { 
     didSet { 
      layer.borderColor = borderColor.cgColor 
     } 
    } 

    @IBInspectable 
    var commaSeparatedButtonTitles: String = "" { 
     didSet { 
      updateView() 
     } 
    } 

    @IBInspectable 
    var textColor: UIColor = .lightGray { 
     didSet { 
      updateView() 
     } 
    } 

    @IBInspectable 
    var selectorColor: UIColor = .darkGray { 
     didSet { 
      updateView() 
     } 
    } 

    @IBInspectable 
    var selectorTextColor: UIColor = .white { 
     didSet { 
      updateView() 
     } 
    } 

    func updateView() { 
     // clear previous history 
     buttons.removeAll() 
     subviews.forEach { (view) in 
      view.removeFromSuperview() 
     } 

     let buttonTitles = commaSeparatedButtonTitles.components(separatedBy: ",") 

     // get names for buttons 
     for buttonTitle in buttonTitles { 
      let button = UIButton(type: .system) 
      button.setTitle(buttonTitle, for: .normal) 
      button.setTitleColor(textColor, for: .normal) 
      button.addTarget(self, action: #selector(buttonTapped(clickedBtn:)), for: .touchUpInside) 
      buttons.append(button) 
     } 

     buttons[0].setTitleColor(selectorTextColor, for: .normal) 

     // configure selector (widget that highlights the selected item) 
     let selectorWidth = frame.width/CGFloat(buttonTitles.count) // length given for selector 
     selector = UIView(frame: CGRect(x: 0, y: 0, width: selectorWidth, height: frame.height)) 
     selector.layer.cornerRadius = 0 
     selector.backgroundColor = selectorColor 
     addSubview(selector) 

     // add buttons to stackview 
     sv = UIStackView(arrangedSubviews: buttons) 
     sv.axis = .horizontal 
     sv.alignment = .fill 
     sv.distribution = .fillProportionally 
     addSubview(sv) 

     // set constraints for stackview 
     sv.translatesAutoresizingMaskIntoConstraints = false 
     sv.topAnchor.constraint(equalTo: self.topAnchor).isActive = true 
     sv.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true 
     sv.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true 
     sv.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true 
    } 

    override func draw(_ rect: CGRect) { 
     layer.cornerRadius = 0 
    } 

    func buttonTapped(clickedBtn: UIButton) { 

     for (index, button) in buttons.enumerated() { 
      if button == clickedBtn { 
       let selectorStartPosition = frame.width/CGFloat(buttons.count) * CGFloat(index) 
       UIView.animate(withDuration: 0.3, animations: { 
        self.selector.frame.origin.x = selectorStartPosition 
       }) 
       button.setTitleColor(selectorTextColor, for: .normal) 
      } else { 
       button.setTitleColor(textColor, for: .normal) 
      } 
     } 
    } 

} 

在故事板,它呈現並提請組件後,就說明這一點:

StoryBoard screenshot

這似乎是正常的。你應該有能力,當你點擊任何其他年份按鈕時,橙色選擇器將移動到那一年。 (這與分段控制相似)。

當我運行它,模擬器給出了這樣:

Sim screenshot

這似乎有點奇怪。 ornage選擇器看起來比storybaord中的更寬一些。所以,我點擊了最後一個按鈕(「2020」),這是結果:

enter image description here

啊,我看的選擇似乎得到它所需要的寬度不正確。在代碼中,你可以看到它獲得了正確的寬度,但由於某種原因,事實並非如此。

爲什麼它得到錯誤的寬度?我是否使用錯誤的變量來計算正確的寬度?

+0

我不會合並自動佈局和幀操作。你應該盡力而爲。 – Paulw11

回答

0

爲什麼要添加視圖來突出顯示按鈕?你應該配置按鈕的選擇狀態。您可以設置色調顏色來設置選定的背景色,併爲所選狀態設置按鈕的標題顏色。

+0

我可以,但後來我無法制作它。當用戶點擊每個按鈕時,該選擇器將滑過。 –

+0

好吧,我明白了。您應該使用約束來定位這些視圖,看起來您正在手動設置框架。 –

+0

我使用YearSelectorSegControl視圖的約束條件,但是這是在Storyboard中完成的。 –