【问题标题】:SearchController’s searchBar added as a UIView subview not being correctly (re)sizedSearchController 的 searchBar 添加为 UIView 子视图未正确(重新)调整大小
【发布时间】:2017-10-25 01:19:25
【问题描述】:

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

请查看图片链接,因为我仍然无法在此处发布图片。 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.
    }
}

【问题讨论】:

  • 这里有类似的问题。无论我尝试了什么,搜索栏的行为都会以一种或另一种方式被破坏。

标签: uiview xcode9 swift4 uisearchcontroller searchbar


【解决方案1】:

我有同样的问题。我到处都添加了框架调整代码。例如,当我从 tableview 建议列表中选择一个项目时,我会调用一个函数。在那个函数里面我写了下面的代码,所以搜索栏在动画后回到了我想要的宽度。我希望有人能提供更专业的解决方案。它在我的代码中看起来不太好,但可以工作。

func(youCallbyTapping) {


DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {

            var searchBarFrame = self.fromSearchController.searchBar.frame
            searchBarFrame.size.width = self.myFrom.frame.size.width - 15
            self.fromSearchController.searchBar.frame = searchBarFrame
            self.toSearchController.searchBar.frame = searchBarFrame
            }
}

【讨论】:

    猜你喜欢
    • 2012-08-28
    • 1970-01-01
    • 2014-09-02
    • 2013-04-12
    • 2023-03-23
    • 2013-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多