Ios Swift分段控制开关导航标题中的多个视图

Ios Swift分段控制开关导航标题中的多个视图,ios,swift,Ios,Swift,我已经看到了另一个问题,如果我在视图中有段控件,这个问题就可以解决了。但是,我在viewDidLoad函数中以编程方式创建了一个段控件,该段控件被设置为导航栏的标题视图。它不允许我引用该段控件,因为它不在nib文件中。我还尝试了通过self.navigationController?.navigationBar.topItem?.titleView.customSC.selectedSegmentIndex引用它的整个字符串,但这也不起作用 代码: 您需要为UISegmentedControl对

我已经看到了另一个问题,如果我在视图中有段控件,这个问题就可以解决了。但是,我在viewDidLoad函数中以编程方式创建了一个段控件,该段控件被设置为导航栏的标题视图。它不允许我引用该段控件,因为它不在nib文件中。我还尝试了通过
self.navigationController?.navigationBar.topItem?.titleView.customSC.selectedSegmentIndex
引用它的整个字符串,但这也不起作用

代码:


您需要为
UISegmentedControl
对象创建属性,并在
viewDidLoad
方法中初始化它:

var segmentedControl: UISegmentedControl!

override func viewDidLoad() {
    super.viewDidLoad()

    let logo = UIImage(named: "image")
    let logoView = UIImageView(frame: CGRect(x: 0, y: 0, width: 100, height: 80))
    logoView.contentMode = .ScaleAspectFit
    logoView.image = logo
    let leftLogo = UIBarButtonItem(customView: logoView)
    self.navigationItem.leftBarButtonItem = leftLogo

    let items = ["Tab 1", "Tab 2", "Tab 3", "Tab 4"]
    let customSC = UISegmentedControl(items: items)
    customSC.selectedSegmentIndex = 0
    navigationController?.navigationBar.topItem?.titleView = customSC
    navigationController?.navigationBar.translucent = false

    // Store instance of UISegmentedControl in property
    self.segmentedControl = customVC

    let requestObj = NSURLRequest(URL: webviewURL)
    webView.loadRequest(requestObj)
}
然后您可以访问它:
self.segmentedControl.selectedSegmentIndex

如果需要使用分段控件处理用户交互,请将此代码添加到
viewDidLoad

self.segmentedControl.addTarget(self, action: "onSegmentedControlValueChanged:", forControlEvents: UIControlEvents.ValueChanged)
还要将此方法添加到类中:

func onSegmentedControlValueChanged(segmentedControl: UISegmentedControl) {
    let newIndex = segmentedControl.selectedSegmentIndex
    // Use newIndex as needed
}

您需要为
UISegmentedControl
对象创建属性,并在
viewDidLoad
方法中初始化它:

var segmentedControl: UISegmentedControl!

override func viewDidLoad() {
    super.viewDidLoad()

    let logo = UIImage(named: "image")
    let logoView = UIImageView(frame: CGRect(x: 0, y: 0, width: 100, height: 80))
    logoView.contentMode = .ScaleAspectFit
    logoView.image = logo
    let leftLogo = UIBarButtonItem(customView: logoView)
    self.navigationItem.leftBarButtonItem = leftLogo

    let items = ["Tab 1", "Tab 2", "Tab 3", "Tab 4"]
    let customSC = UISegmentedControl(items: items)
    customSC.selectedSegmentIndex = 0
    navigationController?.navigationBar.topItem?.titleView = customSC
    navigationController?.navigationBar.translucent = false

    // Store instance of UISegmentedControl in property
    self.segmentedControl = customVC

    let requestObj = NSURLRequest(URL: webviewURL)
    webView.loadRequest(requestObj)
}
然后您可以访问它:
self.segmentedControl.selectedSegmentIndex

如果需要使用分段控件处理用户交互,请将此代码添加到
viewDidLoad

self.segmentedControl.addTarget(self, action: "onSegmentedControlValueChanged:", forControlEvents: UIControlEvents.ValueChanged)
还要将此方法添加到类中:

func onSegmentedControlValueChanged(segmentedControl: UISegmentedControl) {
    let newIndex = segmentedControl.selectedSegmentIndex
    // Use newIndex as needed
}

首先,如果您没有使用Storyboard/XIB/InterfaceBuilder并以编程方式执行所有操作,则可以删除
@IBAction
,因为这意味着
接口生成器操作

其次,最好将分段控件作为变量,以便在需要时更容易访问:
var customSC:UISegmentedControl
-就在
类MyVC:UIViewController{
之后
但是Swift要求在调用超类指定的初始值设定项之前初始化所有变量-
init(nibName-nibNameOrNil:
),因此,让我们初始化它:可以在它的声明中初始化变量:

将var customSC:UISegmentedControl更改为

  var customSC: UISegmentedControl = {
    let items = ["Tab 1", "Tab 2", "Tab 3", "Tab 4"]
    let control = UISegmentedControl(items: items)
    control.selectedSegmentIndex = 0
    return control
    }()
因此,我们不需要在
viewDidLoad
方法中配置分段控件。
问题是,为什么控件不工作是因为您没有向其添加目标。因此,当您更改选定的段时,控件不会向viewcontroller发送任何事件。让我们来解决它。将此方法添加到
ViewDiLoad
的末尾:
customSC.addTarget(self,action:“indexChanged:”,forControlEvents:UIControlEvents.ValueChanged)

现在,当您按下任何一个段时,将调用方法
indexChanged(sender:UISegmentedControl)
,视图控制器将能够做出反应。
通过这种方式将分段控件放在导航栏顶部会更容易:
navigationItem.titleView=customSC
,它比这短得多:
navigationController?.navigationBar.topItem?.titleView=customSC

使用Interface Builder时,可以为WebView使用
修饰符,因为它将自动添加到控制器的主视图并保存在内存中。但是如果以编程方式添加它,则应避免在此上下文中使用弱,以防出现不希望出现的行为(Web视图将在没有强链接(即非弱链接)时立即解除分配,因此基本上,它将在创建后立即解除分配,最终导致
错误访问
错误。要修复它,只需将此更改:
弱var webView:UIWebView!
更改为此
var webView:UIWebView!

因此,在进行小规模重构之后,我们可能会完成类似的工作:

import UIKit
class MyVC: UIViewController {

  var webviewURL: NSURL = NSURL(string: "myURL")!
  var webviewURL2: NSURL = NSURL(string: "myURL")!
  var webviewURL3: NSURL = NSURL(string: "myURL")!
  var webviewURL4: NSURL = NSURL(string: "myURL")!

  var webView: UIWebView!

  var customSC: UISegmentedControl = {
    let items = ["Tab 1", "Tab 2", "Tab 3", "Tab 4"]
    let control = UISegmentedControl(items: items)
    control.selectedSegmentIndex = 0
    return control
    }()

   func indexChanged(sender: UISegmentedControl) {
    switch customSC.selectedSegmentIndex { //error here
    case 0:
      let requestObj = NSURLRequest(URL: webviewURL)
      webView.loadRequest(requestObj)
    case 1:
      let requestObj = NSURLRequest(URL: webviewURL2)
      webView.loadRequest(requestObj)
    case 2:
      let requestObj = NSURLRequest(URL: webviewURL3)
      webView.loadRequest(requestObj)
    case 3:
      let requestObj = NSURLRequest(URL: webviewURL4)
      webView.loadRequest(requestObj)
    default:
      break;
    }
  }

  override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
    super.init(nibName: "myVC", bundle: nil)
  }

  convenience init() {
    self.init(nibName: "myVC", bundle: nil)
    //set the tab bar item's title
    tabBarItem.title = "title"

    //put an image on the tab bar item
    tabBarItem.image = UIImage(named: "image")
  }
  required init(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }


  override func viewDidLoad() {
    super.viewDidLoad()

    let logo = UIImage(named: "image")
    let logoView = UIImageView(frame: CGRect(x: 0, y: 0, width: 100, height: 80))
    logoView.contentMode = .ScaleAspectFit
    logoView.image = logo
    let leftLogo = UIBarButtonItem(customView: logoView)
    self.navigationItem.leftBarButtonItem = leftLogo

    navigationItem.titleView = customSC
    navigationController?.navigationBar.translucent = false

    let requestObj = NSURLRequest(URL: webviewURL)
    webView.loadRequest(requestObj)
  }
}

首先,如果您没有使用Storyboard/XIB/InterfaceBuilder并以编程方式执行所有操作,则可以删除
@IBAction
,因为这意味着
接口生成器操作

其次,最好将分段控件作为变量,以便在需要时更容易访问:
var customSC:UISegmentedControl
-就在
类MyVC:UIViewController{
之后
但是Swift要求在调用超类指定的初始值设定项之前初始化所有变量-
init(nibName-nibNameOrNil:
),因此,让我们初始化它:可以在它的声明中初始化变量:

将var customSC:UISegmentedControl更改为

  var customSC: UISegmentedControl = {
    let items = ["Tab 1", "Tab 2", "Tab 3", "Tab 4"]
    let control = UISegmentedControl(items: items)
    control.selectedSegmentIndex = 0
    return control
    }()
因此,我们不需要在
viewDidLoad
方法中配置分段控件。
问题是,为什么控件不工作是因为您没有向其添加目标。因此,当您更改选定的段时,控件不会向viewcontroller发送任何事件。让我们来解决它。将此方法添加到
ViewDiLoad
的末尾:
customSC.addTarget(self,action:“indexChanged:”,forControlEvents:UIControlEvents.ValueChanged)

现在,当您按下任何一个段时,将调用方法
indexChanged(sender:UISegmentedControl)
,视图控制器将能够做出反应。
通过这种方式将分段控件放在导航栏顶部会更容易:
navigationItem.titleView=customSC
,它比这短得多:
navigationController?.navigationBar.topItem?.titleView=customSC

使用Interface Builder时,可以为WebView使用
修饰符,因为它将自动添加到控制器的主视图并保存在内存中。但是如果以编程方式添加它,则应避免在此上下文中使用弱,以防出现不希望出现的行为(Web视图将在没有强链接(即非弱链接)时立即解除分配,因此基本上,它将在创建后立即解除分配,最终导致
错误访问
错误。要修复它,只需将此更改:
弱var webView:UIWebView!
更改为此
var webView:UIWebView!

因此,在进行了小的重构之后,我们可能会完成一些与之相近的工作