如何在UICollectionViewController的头文件中访问UISegmentedControl?

时间:2016-03-23 06:46:58

标签: ios swift ios7 swift2

所以这个问题相当简单。我有UICollectionViewController (MyProfile.swift),标题部分为(MyProfileHeader.swift)。在后者中,我有一个UISegmentedControl来返回collection view cells中不同数量的项和项(我不想在UICollectionViewController中初始化后一个类的实例)。这是我MyProfile.swift class的代码。我尝试在viewForSupplementaryElementOfKind方法中添加目标以返回不同的查询(有效),但我最终必须访问numberOfItemsInSectioncellForItemAtIndexPath方法中的分段控件。 "testObjects""writeObjects"是通过array中的addTarget方法查询的viewForSupplementaryElementOfKind值。我将indexPath设置为returns error,原因显而易见......我如何访问分段控件?

    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

    var numberOfItems: Int? = 0

    let indexPath = NSIndexPath(forItem: 0, inSection: 0)

    let header = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "header", forIndexPath: indexPath) as! MyProfileHeader


    if header.userContent.selectedSegmentIndex == 1 {
        numberOfItems = textObjects.count
    } else if header.userContent.selectedSegmentIndex == 2 {
        numberOfItems = 0
    } else {
        numberOfItems = photoObjects.count
    }



    print("F: \(numberOfItems!)")
    return numberOfItems!
}

2 个答案:

答案 0 :(得分:1)

当为MyProfile中的集合视图检索标题时,您可以在class MyProfile: UICollectionViewController { ... ... weak var header: MyProfileHeader? ... ... func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView { header = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "header", forIndexPath: indexPath) as! MyProfileHeader return header } 中存储对它的弱引用。

UICollectionViewController

然后,您可以通过numberOfItemsInSection中的任何其他功能访问此内容。

请注意,cellForItemAtIndexPathviewForSupplementaryElementOfKind可以在numberOfItemsInSection中创建标题之前调用,因此当您在cellForItemAtIndexPathlet selectedSegmentIndex = header?.userContent.selectedSegmentIndex ?? 0 //0 is the default value here 中访问它时,或者你应该检查null的任何其他地方,然后假设分段控件是默认值(因为这是第一次显示视图)。像

这样的东西
99999999999999999999

答案 1 :(得分:1)

-1st创建一个UICollectionReusableView子类并将其命名为 SegmentedHeader

-2nd在 SegmentedHeader 类中添加协议以跟踪选择的段。当在collectionView的头部中选择一个段时,协议/委托将传递该段的值

-3rd确保您设置了委托weak var delegate: SegmentedHeaderDelegate?

-4,以编程方式创建segmentedControl添加名为 selectedIndex(_ sender:UISegmentedControl)的目标。按下某个段时,将该段的值传递给协议trackSelectedIndex()函数

protocol SegmentedHeaderDelegate: class {
    func trackSelectedIndex(_ theSelectedIndex: Int)
}

class SegmentedHeader: UICollectionReusableView {

    //MARK:- Programmatic Objects
    let segmentedControl: UISegmentedControl = {
        let segmentedControl = UISegmentedControl(items: ["Zero", "One", "Two"])
        segmentedControl.translatesAutoresizingMaskIntoConstraints = false
        segmentedControl.tintColor = UIColor.red
        segmentedControl.backgroundColor = .white
        segmentedControl.isHighlighted = true
        segmentedControl.addTarget(self, action: #selector(selectedIndex(_:)), for: .valueChanged)
        return segmentedControl
    }()

    //MARK:- Class Property
    weak var delegate: SegmentedHeaderDelegate?

    //MARK:- Init Frame
    override init(frame: CGRect) {
        super.init(frame: frame)

        backgroundColor = .white
        setupAnchors()
    }

    //MARK:- TargetAction
    @objc func selectedIndex(_ sender: UISegmentedControl){

        let index = sender.selectedSegmentIndex

        switch index {

        case 0: // this means the first segment was chosen
            delegate?.trackSelectedIndex(0)
            break

        case 1: // this means the middle segment was chosen
            delegate?.trackSelectedIndex(1)
            break

        case 2: // this means the last segment was chosen
            delegate?.trackSelectedIndex(2)
            break

        default:
            break
        }
    }

    fileprivate func setupAnchors(){

        addSubview(segmentedControl)

        segmentedControl.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 0).isActive = true
        segmentedControl.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 0).isActive = true
        segmentedControl.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true
        segmentedControl.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0).isActive = true
    }

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

在具有UICollectionViewController的类中:

重要 - 确保在viewForSupplementaryElementOfKind中设置委托,否则这些都不起作用

// MAKE SURE YOU INCLUDE THE SegmentedHeaderDelegate so the class conforms to it
class ViewController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, SegmentedHeaderDelegate{

// add a class property for the header identifier
let segmentedHeaderIdentifier = "segmentedHeader"

// add a class property to keep track of which segment was selected. This gets set inside the tracktSelectedIndex() function. You will need this for cellForRowAtIndexPath so you can show whatever needs to be shown for each segment
var selectedSegment: Int?

// register the SegmentedHeader with the collectionView
collectionView.register(SegmentedHeader.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: segmentedHeaderIdentifier)

// inside the collectionView's delegate below add the header
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

        var header: UICollectionReusableView?

        if kind == UICollectionElementKindSectionHeader{

            let segmentedHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: segmentedHeaderIdentifier, for: indexPath) as! SegmentedHeader

            // IMPORTANT >>>>MAKE SURE YOU SET THE DELEGATE or NONE OF THIS WILL WORK<<<<
            segmentedHeader.delegate = self

            // when the scene first appears there won't be any segments chosen so if you want a default one to show until the user picks one then set it here
            // for eg. when the scene first appears the last segment will show
            segmentedHeader.segmentedControl.selectedSegmentIndex = 2

            header = segmentedHeader
        }

        return header!
    }

// inside cellForRowAtIndexPath check the selectedSegmented class property to find out which segment was chosen
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TheCell, for: indexPath) as! TheCell

        // selectedSegment is the class property that gets set inside trackSelectedIndex()
        switch selectedSegment {

            case 0:
            // have the cell display something for the first segment
            break

            case 1:
            // have the cell display something for the middle segment
            break

            case 2:
            // have the cell display something for the last segment
            break

            default:
            break
        }

        return cell
}


// whenever a segment is selected, this function  will get passed the segment's index and you run a switch statement on theSelectedIndex argument then set the selectedIndex class property to match the value from theSelectedIndex argument
func trackSelectedIndex(_ theSelectedIndex: Int) {

        switch theSelectedIndex {

        case 0: // this means the first segment was chosen
            // set the selectedSegment class property so you can use it inside cellForRowAtIndexPath
            selectedSegment = 0
            print("the selected segment is: \(theSelectedIndex)")
            break

        case 1: // this means the middle segment was chosen
            selectedSegment = 1
            print("the selected segment is: \(theSelectedIndex)")
            break

        case 2: // this means the last segment was chosen
            selectedSegment = 2
            print("the selected segment is: \(theSelectedIndex)")
            break

        default:
            break
        }
}