任何人都可以帮助我理解这段代码 - iOS swift

时间:2016-06-18 07:59:39

标签: ios swift

这是我在互联网上创建自定义分段控件的代码。我在理解最后两个函数时遇到了问题, beginTrackingWithTouch layoutSubviews 。这些函数的目的是什么?它们的代码完全是什么

最后,请原谅这个问题。我还是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 个答案:

答案 0 :(得分: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
        }