如何在工具栏上方(或下方)放置工具栏

时间:2016-09-14 18:04:59

标签: swift uitableview scroll

环境:

  • Xcode 7.3.1
  • iOS 9.3
目的:

    一个可滚动的表视图,在相对于滚动表的固定位置(上方或下方)中有一个工具栏(或不同的按钮)。
故事板:
    最初我只是有了tableview并添加了一个工具栏,但是工具栏位于tableview中 我后来为Bottom Bar找到了这个选项:Opaque Toolbar,但无法弄清楚如何利用它/将我的工具栏移动到提供的空间(看起来像我想要的那样)
      storyboard
当前结果:
    如果我只有几个单元格,例如:5或10,那么结果是“好的”,但不是“很棒”:
      okay

    但是,如果我有大量的细胞,例如:20,那么我试图避免的问题就会立即显现出来:

      bad
QUERY:
  • 我可以在Xcode UI中完成我想要的吗?
    • 如果是这样,有人可以提供一些我需要采取的指示/步骤吗?
  • 或者我是否需要在Swift代码中执行此操作?
    • 再次,指针/步骤/通用代码示例表示感谢。


  • WRT 2016-09-15在答案#1编辑

    将初始视图控制器(带按钮的控制器)嵌入到`UINavigationController`中。

    我看不出怎么做,因为我似乎能够在导航控制器中嵌入的唯一东西是标签栏控制器

      embed

    如果尚未创建,请创建一个`UITableViewController`类并将其链接到表视图控制器。

    我已经将class ExistingLocationsViewController: UITableViewController { ... }(以及class ExistingLocationTableViewCell: UITableViewCell { ... })链接起来,我相信,正确

    将此代码添加到类中,以便在查看表视图时使工具栏显示和消失:
        import UIKit
        class ViewController: UITableViewController {
            override func viewDidLoad() {
                super.viewDidLoad()
                navigationController?.isToolbarHidden = false
            }
            override func viewWillDisappear(_ animated: Bool) {
                navigationController?.isToolbarHidden = true
            }
        }
    这应该是你所要做的。如果要编辑工具栏,请在编辑时将其显示,然后再将其隐藏。

    仅供参考,在我的Xcode,iOS版本中,该属性似乎被命名为toolbarHidden不是 **isT**oolbarHidden

    <小时/> 另一种方法(2016-09-17)
    回到一步(或两步),我注意到Table View Controller的一个选项并尝试使用它,但它似乎不起作用。有关详细信息,请参阅图像(和文本内容):
      embed


    当我运行应用程序时,它似乎没有任何区别(再次,见图像):
      embed


    我做错了什么?还是完全误解了Xcode界面?

    2 个答案:

    答案 0 :(得分:5)

    向任何视图添加工具栏的最简单方法之一是将其嵌入NavigationViewController。所有这一切都可以在没有代码的情况下完成:

    1. 选择您当前拥有的视图控制器(我假设UITableViewController)并在编辑器 - &gt;下嵌入选择导航控制器enter image description here

      1. 选择新创建的导航控制器。在栏可见性下的实用工具栏中,选择要显示的工具栏。如果需要,您还可以保留导航栏,否则将其关闭。 enter image description here

      2. 现在您可以在UITableViewController中修改工具栏了。只需将不同的工具栏项(条形按钮项,固定空格键按钮项,灵活栏按钮项)拖到工具栏上即可。请注意,您无法移动工具栏,只能在NavigationViewController中更改其样式。 enter image description here

    2. 修改 由于您有一个不同的初始视图控制器,我建议您稍微区别地解决问题。这需要一些代码:

      1. 将初始视图控制器(带按钮的控制器)嵌入UINavigationController。删除任何其他导航控制器。您的按钮应该只有一个显示UITableViewController的segue。禁用导航控制器中的工具栏和以前一样,由您决定启用导航栏(我建议它)。 enter image description here

      2. 如果尚未创建,请创建一个UITableViewController类并将其链接到Table View Controller。 enter image description here

      3. 将此代码添加到类中,以便在查看表视图时使工具栏显示和消失:

        import UIKit
        
        class ViewController: UITableViewController {
        
            override func viewDidLoad() {
                super.viewDidLoad()
                navigationController?.isToolbarHidden = false
            }
        
            override func viewWillDisappear(_ animated: Bool) {
                navigationController?.isToolbarHidden = true
            }
        
        }
        
      4. 这应该是您必须做的所有事情。如果要编辑工具栏,请在编辑时使其可见,然后再将其隐藏。

    答案 1 :(得分:1)

    解决方案(感谢Christoph!很多

    1. 初步工作

      • 我的工作始于一个由默认UIViewControllerViewController.swift)组成的单页应用。
      • 我在视图中添加了按钮(并调整了它们的外观等)
      • 我添加了UITableViewController并为其创建了我自己的自定义类(MyTableViewController.swift
      • 在表格的原型单元格中,我添加了几个标签来填充数据,并为单元格创建了我自己的自定义类(MyTableViewCell.swift
      • 然后,我从最初的UIViewController按钮到UITableViewController中的表格创建了segues
        • 每个segue都有一个唯一的Identifier稍后将使用它,但现在允许将id从初始视图传递到表视图

          此时,应用程序“工作”,但我希望有一些按钮(在表格的顶部或底部)来处理表格中选择的任何数据。当我开始这个线程时,我添加了一个工具栏,但它基本上固定在原型单元格的下方,当有比单个屏幕上更多的数据行时,它也被滚动关闭并且直到列表一直滚动到最后。
    2. 修复 - a.k.a. Christoph to the Rescue

      • 嵌入 导航控制器中的初始视图开始
        • 我最初对于嵌入到什么内容感到困惑,希望这张照片更加清晰
      • 这样做的结果就是修改了故事板:
      • 然后我转到我的表视图控制器场景并将导航项插入到该视图顶部显示的空间中:
      • 为此,我能够添加 Bar Button Item s:
      • 使用各种自定义代码(下面有更多内容)能够得到这个:
    3. 代码

      • 此时,`ViewController.swift`的代码相对简单:
      import UIKit
      
      class ViewController: UIViewController {
      
          @IBOutlet weak var b1: UIButton!
          @IBOutlet weak var b2: UIButton!
          @IBOutlet weak var b3: UIButton!
          var buttonId: String = ""
      
          override func viewDidLoad() {
              super.viewDidLoad()
              // Do any additional setup after loading the view, typically from a nib.
              b1.titleLabel?.adjustsFontSizeToFitWidth = true
              b2.titleLabel?.adjustsFontSizeToFitWidth = true
              b3.titleLabel?.adjustsFontSizeToFitWidth = true
          }
      
          override func didReceiveMemoryWarning() {
              super.didReceiveMemoryWarning()
              // Dispose of any resources that can be recreated.
          }
      
          override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
              let destination      = segue.destinationViewController as! MyTableViewController
              destination.buttonId = segue.identifier
          }
      }
      
      • “MyTableViewCell.swift”的代码也很简单(至少目前为止):
      import UIKit
      
      class MyTableViewCell: UITableViewCell {
          @IBOutlet weak var l1: UILabel!
          @IBOutlet weak var l2: UILabel!
      
          override func awakeFromNib() {
              super.awakeFromNib()
      
              // Add bordering to bottom of each cell
              let border = CALayer()
              let width = CGFloat(1.0)
              border.borderColor = UIColor.darkGrayColor().CGColor
              border.frame = CGRect(x: 0, y: self.frame.size.height - width, width:  self.frame.size.width, height: self.frame.size.height)
              border.borderWidth = width
              self.layer.addSublayer(border)
          }
      
          override func setSelected(selected: Bool, animated: Bool) {
              super.setSelected(selected, animated: animated)
          }
      }
      
      • 另一方面,“MyTableViewController.swift”的代码更复杂 - 也许是因为它只有更多:
      import UIKit
      
      class MyTableViewController: UITableViewController {
          @IBOutlet weak var b1: UIBarButtonItem!
          @IBOutlet weak var b2: UIBarButtonItem!
          var buttonId: String!
          var oldRow = -1
          // The data below is clearly just for testing, eventually this should be pulled from file or DB
          var locationList: [LocationObject] = [
              LocationObject(name: "name-01", address: "addr-1", selected: false),
              LocationObject(name: "name-02", address: "addr-2", selected: false),
              LocationObject(name: "name-03", address: "addr-3", selected: false),
              LocationObject(name: "name-04", address: "addr-3", selected: false),
              LocationObject(name: "name-05", address: "addr-3", selected: false),
              LocationObject(name: "name-06", address: "addr-3", selected: false),
              LocationObject(name: "name-07", address: "addr-3", selected: false),
              LocationObject(name: "name-08", address: "addr-3", selected: false),
              LocationObject(name: "name-09", address: "addr-3", selected: false),
              LocationObject(name: "name-10", address: "addr-3", selected: false),
              LocationObject(name: "name-11", address: "addr-1", selected: false),
              LocationObject(name: "name-12", address: "addr-2", selected: false),
              LocationObject(name: "name-13", address: "addr-3", selected: false),
              LocationObject(name: "name-14", address: "addr-3", selected: false),
              LocationObject(name: "name-15", address: "addr-3", selected: false),
              LocationObject(name: "name-16", address: "addr-3", selected: false),
              LocationObject(name: "name-17", address: "addr-3", selected: false),
              LocationObject(name: "name-18", address: "addr-3", selected: false),
              LocationObject(name: "name-19", address: "addr-3", selected: false),
              LocationObject(name: "name-10", address: "addr-3", selected: false),
              ]
      
          // This embedded class is to support the above data. It may get replaced in final code
          class LocationObject {
              var name:     String!
              var address:  String!
              var selected: Bool!
      
              init(name: String, address: String, selected: Bool) {
                  self.name      = name
                  self.address   = address
                  self.selected  = false
              }
          }
      
          override func viewDidLoad() {
              super.viewDidLoad()
              // code to hide/expose the navbar (top) and toolbar(bottom) when the view loads
              navigationController?.navigationBarHidden = false 
              navigationController?.toolbarHidden       = true
          }
      
         // code to hide the navbar and toolbar when this view goes away
          override func viewWillDisappear(animated: Bool) {
              navigationController?.navigationBarHidden = true
              navigationController?.toolbarHidden       = true 
          }
      
          override func didReceiveMemoryWarning() {
              super.didReceiveMemoryWarning()
          }
      
          override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
              return 1
          }
      
          override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
              return locationList.count
          }
      
          override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
              let cell = tableView.dequeueReusableCellWithIdentifier("resultCell", forIndexPath: indexPath) as! MyTableViewCell
              let row  = indexPath.row
              let item = locationList[row]
      
              cell.l1.text = item.name
              cell.l2.text = item.address
      
              return cell
          }
      
          override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
              let cell                   = tableView.cellForRowAtIndexPath(indexPath) as! MyTableViewCell
              let row                    = indexPath.row
              cell.accessoryType         = .None
              locationList[row].selected = false
          }
      
          override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
              b1.enabled = true
              let cell                   = tableView.cellForRowAtIndexPath(indexPath) as! MyTableViewCell
              let row                    = indexPath.row
              locationList[row].selected = !locationList[row].selected
              cell.accessoryType         = (locationList[row].selected == true) ? .Checkmark : .None
              cell.highlighted           = false
              cell.setHighlighted(false, animated: true)
      
              // TOGGLE SELECTION
              if oldRow == row {
                  b1.enabled = false
                  let oldIndexPath = NSIndexPath(forRow: oldRow, inSection: 0)
                  tableView.deselectRowAtIndexPath(oldIndexPath, animated: true)
                  oldRow = -1
              }
              else {
                  oldRow = row
              }
          }
      }
      

      而且,简而言之就是这样。我仍然处于开发我的应用程序的早期阶段 - 不知何故,我有理由相信,在我前进的过程中,我会发布更多有关实施的问题,但希望上述内容可以帮助其他可能正在努力解决问题的人,或类似的,问题。

      再次感谢 Christoph 提供有关将视图嵌入导航视图控制器等方面的必要指示。