2017-03-03 3 views
1

Ich habe eine benutzerdefinierte UIControl:Benutzerdefinierte Segmented Steuerung Nicht Schalt Ansichten

import UIKit 

    @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 = 5 
     layer.borderColor = UIColor(red: 239/255, green: 239/255, blue: 239/255, alpha: 1).cgColor 
     layer.borderWidth = 2 

     backgroundColor = UIColor(red: 239/255, green: 239/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: "Nunito",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] 


     UIView.animate(withDuration: 0.5, delay: 0.0, usingSpringWithDamping: 0.90, initialSpringVelocity: 0.8, options: [], animations: { 

      self.thumbView.frame = label.frame 

     }, completion: nil) 
    } 

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

} 

ich emeded es in meinem Viewcontroller und versuchte es programitcally zwischen zwei Ansichten wechseln zu müssen:

import UIKit 

    class FeedViewController: UIViewController { 

    let feedViewSC = FeedViewSC() 

    let firstView: UIView = { 
     let view = UIView() 
     view.backgroundColor = UIColor.red 
     view.translatesAutoresizingMaskIntoConstraints = false 
     return view 
    }() 

    let secondView: UIView = { 
     let view = UIView() 
     view.backgroundColor = UIColor.blue 
     view.translatesAutoresizingMaskIntoConstraints = false 
     return view 
    }() 

    let (width, height) = UIScreen.main.bounds.wh 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     self.view.backgroundColor = UIColor.white 
     view.addSubview(firstView) 
     view.addSubview(secondView) 

     setupContainerViews() 

     firstView.isHidden = false 
     secondView.isHidden = true 

     myTravel.selectedIndex = 0 

     let feedControl = FeedViewSC(frame: CGRect(x: 65, y: 5, width: width-130, height: 35)) 
     feedControl.autoresizingMask = [.flexibleWidth,.flexibleHeight] 

     self.navigationController?.navigationBar.addSubview(feedControl) 
     feedControl.addTarget(self, action: #selector(segmentedControlSwitch), for: .valueChanged) 
    } 

    func segmentedControlSwitch(_ sender: FeedViewSC) { 
     switch feedViewSC.selectedIndex { 

     case 0: 
      firstView.isHidden = false 
      secondView.isHidden = true 

     case 1: 
      firstView.isHidden = true 
      secondView.isHidden = false 


     default: 
      break; 
     } 
    } 

    func setupContainerViews() { 

     firstView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true 
     firstView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor, constant: 8).isActive = true 
     firstView.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor).isActive = true 
     firstView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true 

     secondView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true 
     secondView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor, constant: 8).isActive = true 
     secondView.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor).isActive = true 
     secondView.widthAnchor.constraint(equalTo: view.widthAnchor).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. 
    } 

} 

extension CGRect { 
    var wh: (w: CGFloat, h: CGFloat) { 
     return (size.width, size.height) 
    } 
} 

Ich bin nicht Sicher, was ich tue, ist falsch. Aus irgendeinem Grund wechselt der Code nicht zwischen FirstView und SecondView. Derzeit wird nur die erste Ansicht angezeigt. Bitte beachte, dass ich dies ohne Storyboards und programmgesteuert durchführe.

+0

Ich habe nicht meinen Mac jetzt um mich herum. Aber wenn ich mir deinen Code ansehe, denke ich, dass er etwas damit zu tun hat, wie du 'segmentierterControlSwitch' nennst. –

Antwort

0

Das Problem scheint in segmentiertenControlSwitch-Methode. Sie sollten den Absender im Switch-Fall anstelle der lokalen Variable verwenden, die möglicherweise nicht initialisiert wird.

func segmentedControlSwitch(_ sender: myTripsSC) { 
    switch sender.selectedIndex { 

    case 0: 
     firstView.isHidden = false 
     secondView.isHidden = true 

    case 1: 
     firstView.isHidden = true 
     secondView.isHidden = false 


    default: 
     break; 
    } 
} 

Edit: Ihre vc sollten wie folgt aussehen:

import UIKit 

class FeedViewController: UIViewController { 

let feedViewSC = FeedViewSC() 

let firstView: UIView = { 
    let view = UIView() 
    view.backgroundColor = UIColor.red 
    view.translatesAutoresizingMaskIntoConstraints = false 
    return view 
}() 

let secondView: UIView = { 
    let view = UIView() 
    view.backgroundColor = UIColor.blue 
    view.translatesAutoresizingMaskIntoConstraints = false 
    return view 
}() 

let (width, height) = UIScreen.main.bounds.wh 

override func viewDidLoad() { 
    super.viewDidLoad() 
    self.view.backgroundColor = UIColor.white 
    view.addSubview(firstView) 
    view.addSubview(secondView) 

    setupContainerViews() 

    firstView.isHidden = false 
    secondView.isHidden = true 

    //myTravel.selectedIndex = 0 

    let feedControl = FeedViewSC(frame: CGRect(x: 65, y: 5, width: width-130, height: 35)) 
    feedControl.autoresizingMask = [.flexibleWidth,.flexibleHeight] 

    self.navigationController?.navigationBar.addSubview(feedControl) 
    feedControl.addTarget(self, action: #selector(segmentedControlSwitch), for: .valueChanged) 
} 

func segmentedControlSwitch(_ sender: FeedViewSC) { 
    switch sender.selectedIndex { 

    case 0: 
     firstView.isHidden = false 
     secondView.isHidden = true 

    case 1: 
     firstView.isHidden = true 
     secondView.isHidden = false 


    default: 
     break; 
    } 
} 

func setupContainerViews() { 

    if #available(iOS 9.0, *) { 
     firstView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true 
    } else { 
     // Fallback on earlier versions 
    } 
    if #available(iOS 9.0, *) { 
     firstView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor, constant: 8).isActive = true 
    } else { 
     // Fallback on earlier versions 
    } 
    if #available(iOS 9.0, *) { 
     firstView.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor).isActive = true 
    } else { 
     // Fallback on earlier versions 
    } 
    if #available(iOS 9.0, *) { 
     firstView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true 
    } else { 
     // Fallback on earlier versions 
    } 

    if #available(iOS 9.0, *) { 
     secondView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true 
    } else { 
     // Fallback on earlier versions 
    } 
    if #available(iOS 9.0, *) { 
     secondView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor, constant: 8).isActive = true 
    } else { 
     // Fallback on earlier versions 
    } 
    if #available(iOS 9.0, *) { 
     secondView.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor).isActive = true 
    } else { 
     // Fallback on earlier versions 
    } 
    if #available(iOS 9.0, *) { 
     secondView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true 
    } else { 
     // Fallback on earlier versions 
    } 

} 

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. 
} 

} 

extension CGRect { 
    var wh: (w: CGFloat, h: CGFloat) { 
     return (size.width, size.height) 
    } 
} 
+0

Hallo, ich habe meine Aktion geändert, um zu reflektieren, was es sein sollte, aber es funktioniert immer noch nicht – ajayb

+0

Ich kompilierte Ihre nach der vorgeschlagenen Änderung und es funktionierte. Jetzt muss das Problem anderswo sein. Wenn möglich, teile deinen Code. –

Verwandte Themen