【发布时间】:2015-06-16 04:44:01
【问题描述】:
我正在测试我的 UI,我发现搜索栏有点太窄了,我不喜欢。我还想确保视力较差或手动灵活性较差的人在调出他们想要的界面时不会遇到问题。
所以,我想做的是调整UITextfield 在UISearchbar 内的高度。
我尝试过的:
1. 在 Storyboard 中,添加UISearchbar 高度约束 - 结果:搜索栏大小增加,但里面的UITextField 保持不变。
- 访问
UISearchbar中的UITextField并修改其高度 - 结果:控制台输出显示参数已修改,但在屏幕上,UITextField高度保持不变。
注意 - 我可以使用方法 2 修改 UITextField 的其他参数,并且更改会反映在屏幕上,所以我知道我正在访问 UITextField
方法2的代码,放入UISearchbar所在ViewController的viewDidLoad()中:
for tempView in (self.roomInfoSearchBar.subviews[0] as! UIView).subviews as! [UIView]
{
if let tV = tempView as? UITextField
{
var currentFrameRect = tV.frame
currentFrameRect.size.height = 80
//tV.layer.backgroundColor = UIColor.blueColor().CGColor //This works fine
//tV.layer.cornerRadius = 5 //This works fine
//tV.font = UIFont(name: "Courier", size: 40) //This works fine
println(tV.frame.height) //console output:0.0
tV.frame = currentFrameRect
println(tV.frame) //console output:(0.0, 0.0, 0.0, 80.0)
println(currentFrameRect) //console output:(0.0, 0.0, 0.0, 80.0) - redundant, just checking
println(tV.frame.height) //console output:80.0 - it says 80, but screen shows searchbar definitely not 80.
}
}
我认为它与自动布局有关,无论它在哪里设置,它都能忽略参数。我想继续使用自动布局,因为它为我做了很多工作,但我希望它的行为就像在 Storyboard 中一样,当用户设置设置时,它会在其自动布局中使用这些参数并在可以时抱怨' t 而不是在没有反馈的情况下忽略设置。
编辑:
回应马赫什。我不太了解客观的 C++,但我尽力将您写的内容快速转换为 swift。这就是我所拥有的:
(在我的 viewcontroller.swift 中)
func viewDIdLayoutSubviews()
{
super.viewDidLayoutSubviews()
self.roomInfoSearchBar.layoutSubviews()
var topPadding: Float = 5.0
for view in (self.roomInfoSearchBar.subviews[0] as! UIView).subviews as! [UIView]
{
if let tfView = view as? UITextField
{
var calcheight = self.roomInfoSearchBar.frame.size.height - 10
tfView.frame = CGRectMake(tfView.frame.origin.x, CGFloat(topPadding), tfView.frame.size.width, self.roomInfoSearchBar.frame.size.height - CGFloat(topPadding * 2))
}
}
}
由于在将您的代码转换为 swift 时遇到了一些问题,因此我保留了用于访问文本字段的代码。对于 CGRectMake - swift 抱怨各种类型,包括 topPadding 不是 CGFloat 和最后一个变量(Y 大小),它不喜欢将 CGFloat 与 Float 混合,所以我也必须改变它。
不幸的是,它似乎不起作用。我在 Storyboard 中将 UISearchbar 的高度更改为 80,然后我得到了一个非常高的搜索栏,其文本字段覆盖了总高度的 1/3。
编辑 #2:合并 Yuyutsu 和更正版的 Mahesh 代码。
仍然不完美,但更接近。 Yuyutsu 的代码有效,但正如我的 cmets 中所述,该字段不居中,第一次加载视图时,调整大小也是可见的(从高度 A 跳到高度 B)。另一个缺陷是,因为一旦方向改变,调整大小是在viewDidAppear 完成的,所以字段会返回到固有大小。
我的代码基于 Yuyutsu 的:
override func viewDidAppear(animated: Bool)
{
super.viewDidAppear(animated)
var roomInfoSearchBarFrame = roomInfoSearchBar.frame
var newHeight: CGFloat = 60
for subView in roomInfoSearchBar.subviews
{
for subsubView in subView.subviews
{
if let textField = subsubView as? UITextField
{
var currentTextFieldFrame = textField.frame
var recenteredY = (roomInfoSearchBarFrame.height - newHeight)/2
var newTextFieldFrame = CGRectMake(textField.frame.minX, recenteredY, textField.frame.width, newHeight)
textField.frame = newTextFieldFrame
textField.borderStyle = UITextBorderStyle.RoundedRect
textField.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
//textField.backgroundColor = UIColor.redColor()
// textField.font = UIFont.systemFontOfSize(20)
}
}
}
}
查看 Yuyutsu 的代码,我想知道我还能在哪里进行此调整,我通过另一个 stackoverflow 帖子遇到了link。根据我阅读的内容,我看到 Mahesh 的答案应该有效。这就是我意识到它为什么不起作用的地方 - 我需要覆盖func viewWillLayoutSubviews()。
当前代码:保持大小随方向变化。但是尺寸跳跃仍然可见(它不应该是可见的)
override func viewWillLayoutSubviews()
{
super.viewWillLayoutSubviews()
var roomInfoSearchBarFrame = roomInfoSearchBar.frame
var newHeight: CGFloat = 60
for subView in roomInfoSearchBar.subviews
{
for subsubView in subView.subviews
{
if let textField = subsubView as? UITextField
{
var currentTextFieldFrame = textField.frame
var recenteredY = (roomInfoSearchBarFrame.height - newHeight)/2
var newTextFieldFrame = CGRectMake(textField.frame.minX, recenteredY, textField.frame.width, newHeight)
textField.frame = newTextFieldFrame
textField.borderStyle = UITextBorderStyle.RoundedRect
textField.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
//textField.backgroundColor = UIColor.redColor()
// textField.font = UIFont.systemFontOfSize(20)
}
}
}
}
所以现在,唯一剩下的就是尝试让文本字段在视图可见之前设置大小,这样用户就不会看到大小变化。
最终编辑:完全工作的代码 在 Yuyutsu 的额外帮助下,下面的代码可以完成我想要的一切 - 从设定的大小开始,字段居中,可以很好地处理旋转。
override func viewDidLayoutSubviews()
{
super.viewDidLayoutSubviews()
self.roomInfoSearchBar.layoutIfNeeded()
self.roomInfoSearchBar.layoutSubviews()
var roomInfoSearchBarFrame = roomInfoSearchBar.frame
var newHeight: CGFloat = 60 //desired textField Height.
for subView in roomInfoSearchBar.subviews
{
for subsubView in subView.subviews
{
if let textField = subsubView as? UITextField
{
var currentTextFieldBounds = textField.bounds
currentTextFieldBounds.size.height = newHeight
textField.bounds = currentTextFieldBounds
textField.borderStyle = UITextBorderStyle.RoundedRect
//textField.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
}
}
}
}
谢谢悠悠。 感谢 Mahesh 从一开始就提出了最终解决方案,只是遗漏了一些关键部分。
【问题讨论】:
-
Final 可以通过使用 Mahesh 的填充思想更加方便。本质上,您根据
roomInfoSearchBar.frame减去 2 * somePadding(somePadding 是您想要的 searchField 和 textField 之间的空间)计算newHeight。一旦你设置好了,你就可以在 Storyboard 中调整 searchBar 的大小,文本字段也会随之调整。如果要更改填充,只需修改viewDidLayoutSubviews()即可。 -
最好的解决方案是使用
UITextField并将放大镜图像添加到其leftView。真的,你会解决很多入侵UISearchBar引起的问题。 -
感谢我使用您的最终代码修复的所有问题。
-
不适用于 iOS11/swift 4。
-
检查我的答案。还在工作...
标签: swift autolayout uisearchbar