我是快速开发和堆栈溢出的新手,如果有人能够对我正在搜索的大小调整问题有所了解,我真的很感激 . 我无法在屏幕中正确调整搜索栏的大小 . 我创建了一个简单版本的项目来简化奇怪行为的再现 . 它是一个带有tableView对象的ViewController,用于显示searchBar搜索的结果 . 我不希望搜索栏与表格单元格一起滚动,所以我在Main.storyboard中的tableView上方的searchBar创建了一个UIView作为占位符,并为它们添加了必要的约束,因此可以正确调整它们的大小不同的屏幕尺寸和方向 - 事实上,自动布局似乎工作正常 .

请参阅图片链接,因为我仍然无法在此处发布图片 . Main.storyboard image

我也不想在故事板中使用UISearchBar对象,因为我想稍后在我的代码中控制它 . 因此,我以编程方式将SearchController searchBar添加为UIview子视图,其中包含(显然所有)需要的约束以及UIview . 另外,正如你所看到的,tableView和UIView的宽度比屏幕宽度略小,它与我发现的其他帖子有一点不同,它们都完全伸展到屏幕边缘 - 我不知道这是否重要 . 我在xcode 9.0.1(9A1004)上使用swift 4 .

问题:

如您所见,searchBar右边缘经过UIView框架右边缘 . 当它被点击时,取消按钮也会超过屏幕限制 .

searchBar image 1

更为奇怪的是,当方向更改为横向时,searchBar宽度最初不会随UIView延伸 . 但是当点击searchBar时,其宽度返回以超过屏幕限制 . 当点击取消时,searchBar宽度继续大于屏幕宽度 . 无论我选择的屏幕大小和方向,都会出现此问题 .

到目前为止我尝试了什么:

这个项目包含我能找到的所有推荐属性和约束,但我没有设法使用的属性 setTranslatesAutoresizingMaskIntoConstraints 除外 . 在swift 4上,我只发现了一个类似的 translatesAutoresizingMaskIntoConstraints ,但我无法使它工作,它返回 “Cannot call value of non-function type 'Bool’” .

// searchController.searchBar.setTranslatesAutoresizingMaskIntoConstraints(true)    
searchController.searchBar.translatesAutoresizingMaskIntoConstraints(true)   (!) Cannot call value of non-function type 'Bool'

帖子Display UISearchController's searchbar programmatically是一个非常好的帖子,它与我的最相似(除了它延伸到左边,我的情况它确实做到了),但它没有用 . 我还意识到@kcstricks将searchBar宽度设置为self.view.frame.size.width而不是UIview框架宽度 .

// self.searchController.searchBar.frame.size.width = self.view.frame.size.width
self.searchController.searchBar.frame.size.width = searchBarPlaceholderView.frame.size.width

通过更改它,解决了初始的searchBar行为 . 现在它最初显示正确:

searchBar image 2

但是一旦它被点击,奇怪的行为返回并再也不会恢复正常 .

searchBar image 3

searchBar image 4

我也尝试将主代码移动到viewDidAppear方法,但没有结果 . 我在哪里失败?

其他研究过的堆栈溢出帖子:
Fixed UISearchBar using UISearchController - Not using header view of UITableView
UISearchController's searchBar doesn't fill full width
UISearchBar width doesn't change when its embedded inside a UINavigationBar

非常感谢你提前 .

完整代码:

//  ViewController.swift
//  SearchBarTests
//  Copyright © 2017 equilibrio. All rights reserved.

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UISearchResultsUpdating {

    @IBOutlet var myTableView: UITableView!
    @IBOutlet var searchBarPlaceholderView: UIView!

    var searchController: UISearchController!

    var selectedBeers = [Beer]()

    struct Beer {
        var type = String()
        var examples = String()
    }

    var beers = [Beer(type: "American Lager", examples: "Budweiser, Coors, Pabst Blue Ribbon"),
                 Beer(type: "German Helles", examples: "Victory Helles Lager, Stoudt's Gold Lager"),
                 Beer(type: "German Pilsner", examples: "Tröegs Sunshine Pils, Bavaria, Sierra Nevada's Nooner Pilsner"),
                 Beer(type: "Belgian Gueuze", examples: "")]

    // Delegates and Datasources
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.selectedBeers.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.subtitle, reuseIdentifier: "cell")

        cell.textLabel?.text = self.selectedBeers[indexPath.row].type
        cell.detailTextLabel?.text = self.selectedBeers[indexPath.row].examples
        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("Row \(indexPath.row) selected")
    }

    func updateSearchResults(for searchController: UISearchController) {
        if searchController.searchBar.text! == "" {
            selectedBeers = beers
        } else {
            selectedBeers = beers.filter { $0.type.lowercased().contains(searchController.searchBar.text!.lowercased()) }
        }

        self.myTableView.reloadData()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        selectedBeers = beers

        self.searchController = UISearchController(searchResultsController: nil)
        self.searchController.searchResultsUpdater = self
        self.searchController.dimsBackgroundDuringPresentation = false
        self.searchController.searchBar.delegate = self
        definesPresentationContext = true

        self.searchBarPlaceholderView.addSubview(self.searchController.searchBar)
        self.searchController.searchBar.searchBarStyle = UISearchBarStyle.minimal
        // self.searchController.searchBar.frame.size.width = self.view.frame.size.width
        self.searchController.searchBar.placeholder = "Type desired beer style..."
        self.searchController.searchBar.frame.size.width = searchBarPlaceholderView.frame.size.width
        self.searchController.searchBar.sizeToFit()

        // searchController.searchBar.setTranslatesAutoresizingMaskIntoConstraints(false)
        // searchController.searchBar.translatesAutoresizingMaskIntoConstraints(true)

        self.myTableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        self.myTableView.reloadData()
    }

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