2016-06-18 76 views
0

这是创建一个自定义分段控件的代码,我通过互联网找到。我在理解最后两项功能时遇到问题,beginTrackingWithTouchlayoutSubviews。这些功能的目的是什么,它们的代码究竟做了什么任何人都可以帮我理解这个代码 - iOS swift

最后,请原谅这个问题。我仍然是iOS开发人员的初学者,我只是寻求帮助。

@IBDesignable class CustomSegmentedControl : UIControl { 
    private var labels = [UILabel]() 
    var items = ["Item 1","Item 2"] { 
     didSet { 
      setUpLabels() 
     } 
    } 
    var thumbView = UIView() 
    var selectedIndex : Int = 0 { 
     didSet { 
      displayNewSelectedIndex() 
     } 
    } 
    override init(frame: CGRect) { 
     super.init(frame: frame) 
     setupView() 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     setupView() 
    } 
    func setupView() { 
     //layer.cornerRadius = frame.height/2 
     layer.borderColor = UIColor.blackColor().CGColor 
     layer.borderWidth = 2 

     backgroundColor = UIColor.clearColor() 
     setUpLabels() 

     insertSubview(thumbView, atIndex: 0) 
    } 
    func setUpLabels() { 
     for label in labels { 
      label.removeFromSuperview() 
     } 
     labels.removeAll(keepCapacity: true) 
     for index in 1...items.count { 
      let label = UILabel(frame: CGRectZero) 
      label.text = items[index-1] 
      label.textAlignment = .Center 
      label.textColor = UIColor.blackColor() 
      self.addSubview(label) 
      labels.append(label) 
     } 
    } 
    func displayNewSelectedIndex() { 
     let label = labels[selectedIndex] 
     self.thumbView.frame = label.frame 
    } 
    override func layoutSubviews() { 
     super.layoutSubviews() 
     var selectFrame = self.bounds 
     let newWidth = CGRectGetWidth(selectFrame)/CGFloat(items.count) 
     selectFrame.size.width = newWidth 
     thumbView.frame = selectFrame 
     thumbView.backgroundColor = UIColor.grayColor() 
     //thumbView.layer.cornerRadius = thumbView.frame.height/2 

     let labelHeight = self.bounds.height 
     let labelWidth = self.bounds.width/CGFloat(labels.count) 

     for index in 0..<labels.count { 
      let label = labels[index] 
      let xPosition = CGFloat(index) * labelWidth 
      label.frame = CGRectMake(xPosition, 0, labelWidth, labelHeight) 
     } 
    } 
    override func beginTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?) -> Bool { 
     let location = touch.locationInView(self) 
     var calculatedIndex : Int? 

     for (index, item) in labels.enumerate() { 
      if item.frame.contains(location) { 
       calculatedIndex = index 
      } 

      if calculatedIndex != nil { 
       selectedIndex = calculatedIndex! 
       sendActionsForControlEvents(.ValueChanged) 
      } 
     } 
     return false 
    } 
} 
+1

请阅读官方文档:[UIControl.beginTrackingWithTouch(_:withEvent:方法)(https://开头developer.apple.com/library/ios/documentation/UIKit/Reference/UIControl_Class/#//apple_ref/occ/instm/UIControl/beginTrackingWithTouch:withEvent :) and [UIView.layoutSubviews](https://developer.apple.com) /library/ios/documentation/UIKit/Reference/UIView_Class/index.html#//apple_ref/occ/instm/UIView/layoutSubviews)。仅仅通过阅读方法描述,'layoutSubviews'有点难以掌握。请阅读有关视图布局的官方指南。 – Sulthan

回答

2

我可以解释开始跟踪方法,另一种是可研究的,我认为这样

/*** beginTrackingWithTouch.. method to customize tracking. ***/ 
    // Parameters : touch : this returns the touch that occurred at a certain point in the view. withEvent, returns the UIEvent 
    // associated with the touch. 
    // Return Type: Boolean. 
    override func beginTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?) -> Bool { 
      let location = touch.locationInView(self) // This line returns the location of touch in the view. This location is in CGPoint. 
      var calculatedIndex : Int? 

      for (index, item) in labels.enumerate() { /// enumeration of an array gives you sequence type of integer and corresponding element type of the array. 
       if item.frame.contains(location) {  /// so labels.enumerate returns the key value pairs like so : [(0, labelatIndex0), (1, labelatIndex1).. and so on.] 
        calculatedIndex = index   /// here index is the key, and item is the value (label.) 
    // So for every label/index pair, you check whether the touch happened on the label by getting the frame of the label and checking if location is a part of the frame 
    /// You equate the index to calculatedIndex 
       } 
    // Now you if your calculated index is a valid number, you class, which extends UIControl, will call its method stating the change of value(sendActionsForControlEvents). 
    // This in turn, will send a message to all the targets that have been registered using addTarget:action:forControlEvents: method. 
       if calculatedIndex != nil { 
        selectedIndex = calculatedIndex! 
        sendActionsForControlEvents(.ValueChanged) 
       } 
      } 

      return false 
     } 
+1

谢谢,你帮了我很多 –

+0

很高兴我能帮上忙。 @AliAlebrahim –

相关问题