Ios 以编程方式将UIControl添加到导航栏标题中-Swift

Ios 以编程方式将UIControl添加到导航栏标题中-Swift,ios,swift,uisegmentedcontrol,Ios,Swift,Uisegmentedcontrol,我正在尝试将我创建的自定义UI分段控件添加到根视图控制器的导航栏中。这是我的密码: 分段控制: @IBDesignable class FeedViewSC: UIControl { fileprivate var labels = [UILabel]() var thumbView = UIView() var items: [String] = ["Tab1", "Tab2"] { didSet { setupLabels() } } var sel

我正在尝试将我创建的自定义UI分段控件添加到根视图控制器的导航栏中。这是我的密码:

分段控制:

@IBDesignable class FeedViewSC: UIControl {


fileprivate var labels = [UILabel]()
var thumbView = UIView()

var items: [String] = ["Tab1", "Tab2"] {
    didSet {
        setupLabels()
    }

}

var selectedIndex : Int = 0 {
    didSet{
        displayNewSelectedIndex()
    }
}

@IBInspectable var font : UIFont! = UIFont.systemFont(ofSize: 13) {
    didSet {
        setFont()
    }
}

override init(frame: CGRect) {
    super.init(frame: frame)

    setupView()
}

required init?(coder: NSCoder) {
    super.init(coder: coder)
    setupView()
}

func setupView() {

    layer.cornerRadius = 2
    layer.borderColor = UIColor(red: 2/255, green: 239/255, blue: 23/255, alpha: 1).cgColor

    backgroundColor = UIColor(red: 239/255, green: 29/255, blue: 239/255, alpha: 1)

    setupLabels()

    insertSubview(thumbView, at: 0)

}


func setupLabels() {
    for label in labels {
        label.removeFromSuperview()
    }

    labels.removeAll(keepingCapacity: true)

    for index in 1...items.count {
        let label = UILabel(frame: CGRect.zero)
        label.text = items[index-1]
        label.textAlignment = .center
        label.font = UIFont(name: "timesnr",size: 17)
        label.textColor = UIColor(red: 51/255, green: 51/255, blue: 51/255, alpha: 1)
        self.addSubview(label)
        labels.append(label)
    }
}

override func layoutSubviews() {
    super.layoutSubviews()

    var selectFrame = self.bounds
    let newWidth = selectFrame.width / CGFloat(items.count)
    selectFrame.size.width = newWidth
    thumbView.frame = selectFrame
    thumbView.backgroundColor = UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 1)
    thumbView.layer.cornerRadius = 5

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

    for index in 0...labels.count - 1 {

        let label = labels[index]

        let xPosition = CGFloat(index) * labelWidth
        label.frame = CGRect(x: xPosition, y: 0, width: labelWidth, height: labelHeight)
    }

}

override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
    let location = touch.location(in: self)

    var calculatedIndex: Int?
    for (index, item) in labels.enumerated() {
        if item.frame.contains(location){
            calculatedIndex = index
        }
    }
    if calculatedIndex != nil {
        selectedIndex = calculatedIndex!
        sendActions(for: .valueChanged)
    }

    return false

}


func displayNewSelectedIndex (){

    if(self.selectedIndex == -1){
        self.selectedIndex = self.items.count-1
    }

    let label = labels[selectedIndex]
}

func setFont(){
    for item in labels {
        item.font = font
    }
}

}
我希望将此分段控件添加到我的VC:

class FeedViewController: UIViewController {


let feedViewSC: FeedViewSC = {
    let sc = FeedViewSC()
    sc.translatesAutoresizingMaskIntoConstraints = false
    return sc
}()

override func viewDidLoad() {
    super.viewDidLoad()
    self.view.backgroundColor = UIColor.white
    view.addSubview(feedViewSC)
    setupFeedViewSC()
}

func setupFeedViewSC() {
    feedViewSC.topAnchor.constraint(equalTo: self.topLayoutGuide.bottomAnchor, constant: 5).isActive = true
    feedViewSC.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    feedViewSC.heightAnchor.constraint(equalToConstant: 35).isActive = true
    feedViewSC.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 60).isActive = true
    feedViewSC.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -60).isActive = true
}

override func viewDidAppear(_ animated: Bool) {
    let img = UIImage()
    self.navigationController?.navigationBar.shadowImage = img
    self.navigationController?.navigationBar.setBackgroundImage(img, for: UIBarMetrics.default)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

如果您可以告诉我如何将我的自定义UIControl添加到我的视图控制器的导航栏标题。

如果FeedViewController是导航控制器的初始视图控制器,您可以通过

let feedControl = FeedViewSC(frame: (self.navigationController?.navigationBar.bounds)!)
feedControl.autoresizingMask = [.flexibleWidth,.flexibleHeight]
self.navigationController?.navigationBar.addSubview(feedControl)
feedControl.addTarget(self, action: #selector(FeedViewController.changingTab), for: .valueChanged)
至少我不认为这对在导航栏中获取它不起作用的原因

这也不是问题的一部分,但如果您在IB中看到您的控件时遇到任何问题,我建议您

override func prepareForInterfaceBuilder() {
    super.prepareForInterfaceBuilder()
    layer.cornerRadius = 2
    layer.borderColor = UIColor(red: 2/255, green: 239/255, blue: 23/255, alpha: 1).cgColor
    backgroundColor = UIColor(red: 239/255, green: 29/255, blue: 239/255, alpha: 1)
    setupLabels()
    insertSubview(thumbView, at: 0)
}
至于控件本身,我没有测试它,但您的事件和处理可能与更改的值略有不同,我不确定

您还可以将控制器的导航栏设置为一个特殊的可设计类,并且永远不要将其添加到代码中,但您可能需要在viewDidLoad中获得一个引用才能使用它。可设计项看起来像

import UIKit

    @IBDesignable class DesignableNavBar: UINavigationBar {

        var feedControl : FeedViewSC!

        override init(frame: CGRect) {
            super.init(frame: frame)

            setupView()
        }

        required init?(coder: NSCoder) {
            super.init(coder: coder)
            setupView()
        }

        func setupView() {
            if feedControl == nil{
                feedControl = NavControl(frame: self.bounds)
                feedControl.autoresizingMask = [.flexibleHeight,.flexibleWidth]
                self.addSubview(feedControl)
            }

        }

        override func prepareForInterfaceBuilder() {
            super.prepareForInterfaceBuilder()
            setupView()
        }


    }
然后在你的控制器中,比如说viewDidLoad,你可以这样做

if let navController = self.navigationController{
        if navController.navigationBar is DesignableNavBar{
            let control = (navController.navigationBar as! DesignableNavBar). feedControl
            control?.addTarget(self, action: #selector(ViewController.changingTab), for: .valueChanged)
        }
    }

你也可以在故事板中完成。拖动导航栏顶部的uiview并将类名更改为FeedViewSC。您可以根据需要调整大小。我知道您已将其标记为正确的。如果您希望在导航控制器中看到它,我已对其进行了更新。只需更改uinavigationcontroller中的导航栏以匹配上面的类,即可在导航栏的故事板中进行设计。享受