动画 UISearchBar 框架的宽度

Posted

技术标签:

【中文标题】动画 UISearchBar 框架的宽度【英文标题】:Animating the width of UISearchBar frame 【发布时间】:2012-03-05 18:36:42 【问题描述】:

是否可以为 UISearchBar 的框架宽度设置动画?我发现当我应用 uiview 动画来扩大搜索栏的范围时,它会立即弹出到最终结果,就好像对象内部正在控制它的动画方式,并且不允许我顺利地对其应用我自己的动画。

如果我为它移动平滑的位置设置动画,但我怀疑文本输入根据取消按钮的存在进行调整这一事实可能意味着我们无法通过 UIView 动画为宽度设置动画。下面的示例 sn-p 将条从 x = 0 滑动到 100,但将宽度弹出到 600 像素宽。

CGRect searchBarFrame = self.searchViewController.searchBar.frame;
searchBarFrame.origin.x = 100;
searchBarFrame.size.width = 600;
[UIView animateWithDuration:1.0 
                      delay:0.0 
                    options:0 
                 animations:^
                     self.searchViewController.searchBar.frame = searchBarFrame;
                 
                 completion:^(BOOL completion)
                 ];

【问题讨论】:

好像是个bug,能否提供一些测试代码? 我更新了问题以包括我的发现,即当我尝试更改宽度而不是位置时它会弹出。 乔伊,我在一个项目中,我有两个不同的搜索栏并排,我正在尝试和你做同样的事情,得到相同的结果。如果您最终找到解决方案,请告诉我。如果我找到任何东西,我会告诉你的。 我的问题***.com/questions/68571676/… 【参考方案1】:

UISearchBar 存在“问题”,因为内部视图强制调整大小以忽略动画。但是,这可以通过使用 -layoutSubviews 来克服。我在下面的项目中包含了扩展和收缩代码

[UIView animateWithDuration:.3
                 animations:^ 
                     CGRect newBounds = locationSearch.frame;
                     newBounds.size.width += 215; //newBounds.size.width -= 215; to contract
                     locationSearch.frame = newBounds;
                     [locationSearch layoutSubviews];
                 ];

希望这会有所帮助。

【讨论】:

很抱歉重新打开这个,但我在 ios 6.0 中这样做了,搜索栏后面会出现一个闪烁的 UISegmentedControl 动画。我假设它是一个与 UISearchBar 关联的控件——它不是我启用的控件,我使用的是香草搜索栏。我设法通过在 IB 的 UISearchBar 上启用 Clip Subviews 来摆脱它,但这让我想知道这种动画 UISearchBar 的方法是否有问题。【参考方案2】:

仅供参考,您可以使用 UIViewAnimationOption 而不是显式调用 layoutsubviews, 所以代码看起来像这样..

[UIView animateWithDuration:0.5
                              delay:0
                            options:UIViewAnimationOptionLayoutSubviews
                         animations:^
                             //Set the frame you want to the search bar
                         
                         completion:^(BOOL finished) 

                         ];

【讨论】:

+1 这比在动画块中调用layoutSubviews 更简洁,而且效果很好。谢谢!【参考方案3】:

这是在 swift 中克服仅向 Left 侧放大的方法

(当用户开始/结束编辑时,此代码将在左侧放大/缩小 searchBar 93 像素)


    SharedNavigationbBar 是实现 UISearchBarDelegate 的 UIView searchBarWidth 是保持 UISearchBar 宽度的约束的出口

    故事板或 nib 文件中存在自动布局约束必须,以允许调整到左侧的大小。 在这种情况下,相邻的左侧组件是 UIButton


    添加以下代码作为扩展或在您的类中执行动画调整大小。

extension SharedNavigationBar: UISearchBarDelegate

//amount of pixels to enlarge to the left
 private var offsetSearchBarLeft:CGFloat
    
    get 
        return 93
    
 

///Enlarges search bar
 func searchBarTextDidBeginEditing(searchBar: UISearchBar) 

   self.animateSearchBar(self.searchBar, enlarge: true)
 

///Shrinks search bar
 func searchBarTextDidEndEditing(searchBar: UISearchBar) 

   self.animateSearchBar(self.searchBar, enlarge: false)
 

//shrinks or enlarge the searchbar (this will be the function to call inside the animation)
 private func animateSearchBar(searchBar:UISearchBar, enlarge:Bool)
 
     ///Important here, for this to work, the option and the searchbar size must be handled this way
    UIView.animateWithDuration(0.3, delay: 0.0, options: UIViewAnimationOptions.LayoutSubviews, animations:  [weak self] () -> Void in

    let multiplier: CGFloat = enlarge ? 1 : -1

    let origin = searchBar.frame.origin.x + self!.offsetSearchBarLeft * multiplier
    let width = searchBar.frame.width + self!.offsetSearchBarLeft * multiplier

    //This Block of code, setting the new frame, needs to be inside the animation in order to work
    var newBounds:CGRect  = searchBar.frame;
    newBounds.origin.x = origin
    newBounds.size.width = width

    //Sets the new frame
    self?.searchBarWidth.constant = width
    searchBar.frame = newBounds

   , completion: nil)
 


【讨论】:

以上是关于动画 UISearchBar 框架的宽度的主要内容,如果未能解决你的问题,请参考以下文章

无法为 UISearchBar 的框架或边界设置动画

UISearchBar 没有出现

UINavigationController 中的 UISearchBar,取消按钮不可选

如果单击 UISearchBar,则更改 UITableView 位置:[使用 ModernSearchBar]

UISearchBar:奇怪的扩展动画

自定义 UISearchController 动画