【问题标题】:UISearchBar animating into place when superview lays out subviews. How to disable?当 superview 布置子视图时 UISearchBar 动画到位。如何禁用?
【发布时间】:2020-02-22 02:07:18
【问题描述】:

我的问题: 我有一个用户入职流程,它使用UINavigationController 来展示入职流程中的每个步骤。当在其中推送带有UISearchBars 的视图控制器时,UISearchBars 正在动画到位。

我的问题是什么样的: https://youtu.be/TKPLeJ9FmI4(问题发生在0:270:320:41

我收集到的信息: 这似乎发生在堆栈中的前一个视图控制器在推送下一个视图控制器之前执行异步功能,并且可能没有完成异步函数,直到UISearchBar 已经动画到位。

我的尝试:我尝试子类化UISearchBar 并确保layoutSubviews 不是通过UIView.performWithoutAnimation 进行动画处理:

import UIKit

class SearchBar: UISearchBar {
    override func layoutSubviews() {
        UIView.performWithoutAnimation {
            super.layoutSubviews()
        }
    }
}

同样,我尝试确保UISearchBar 的超级视图在布置子视图时没有动画:

class MyViewController: UIViewController {
    @IBOutlet var searchBar: UISearchBar!

    override func viewDidLayoutSubviews() {
        UIView.performWithoutAnimation {
            super.viewDidLayoutSubviews()
        }
    }
}

我想知道的是:由于很难确定动画的确切原因,我很好奇是否有一种方法可以简单地阻止 UISearchBar 完全停止动画。我永远不会真正需要为UISearchBar 设置动画。

【问题讨论】:

    标签: ios swift uiview uikit uiviewanimation


    【解决方案1】:

    这在 Objective-C 中对我有用。看起来你有足够的能力把它翻译成 Swift:

      [[UISearchBar appearance] setBackgroundImage:[UIImage new]
                                    forBarPosition:UIBarPositionAny
                                        barMetrics:UIBarMetricsDefault];
    
      [[UISearchBar appearance] setBackgroundImage:[UIImage new]
                                    forBarPosition:UIBarPositionAny
                                        barMetrics:UIBarMetricsDefaultPrompt];
    
    [self.searchBar setSearchFieldBackgroundImage:finalImage forState:UIControlStateNormal];
    

    其中“finalImage”是您在代码中绘制的图像,该图像返回与 UISearchBar 矩形大小相同的 UIImage。您可以找到方法来绘制您想要的背景颜色的图像,然后将图像的角变圆。这也是在 Objective-C 中的。

    - (UIImage *)imageWithColor:(UIColor *)color withSize:(CGRect)imageRect {
      UIGraphicsBeginImageContext(imageRect.size);
      CGContextRef context = UIGraphicsGetCurrentContext();
    
      CGContextSetFillColorWithColor(context, [color CGColor]);
      CGContextFillRect(context, imageRect);
    
      UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
      UIGraphicsEndImageContext();
    
      return image;
    }
    
    - (UIImage *)roundImage:(UIImage *)image withRadius:(CGFloat)radius {
      CGRect rect = CGRectMake(0.0, 0.0, 0.0, 0.0);
      rect.size = image.size;
      UIGraphicsBeginImageContextWithOptions(image.size, NO, [UIScreen mainScreen].scale);
      UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect
                                                      cornerRadius:radius];
      [path addClip];
      [image drawInRect:rect];
    
      image = UIGraphicsGetImageFromCurrentImageContext();
      UIGraphicsEndImageContext();
    
      return image;
    }
    

    所以 UISearchBar 的完整声明是这样的:

      self.searchBar = [UISearchBar new];
      CGRect rect = CGRectMake(0.0, 0.0, 44, 35);
      UIImage *colorImage = [self imageWithColor:[UIColor whiteColor] withSize:rect];
      UIImage *finalImage = [self roundImage:colorImage withRadius:10.0];
      [self.searchBar setSearchFieldBackgroundImage:finalImage forState:UIControlStateNormal];
      [self.searchBar setTranslatesAutoresizingMaskIntoConstraints:false];
      [self.view addSubview:self.searchBar];
    

    这是我发现删除 Apple 添加的所有时髦动画并根据需要自定义背景的唯一方法。祝你好运(对于那些因为它不在 Swift 中而拒绝投票的人,你应该知道 Swift 是 Ruby 2.0 和一种 meme 语言,直到真正的编码人员使它不是 meme 语言,所以坚持使用 Objective-C)。

    祝你好运

    编辑

    如果您使用布局约束,请确保您设置了约束,如果您不使用约束,则删除

      [self.searchBar setTranslatesAutoresizingMaskIntoConstraints:false];
    

    然后设置 UISearchBar 的框架

    【讨论】:

    • 它看起来很hacky,但我明天一定会试试的。谢谢你的建议。我希望我能弄清楚如何禁用这个东西。如果我让它工作,我会发布 Swift 翻译,如果你愿意,你可以编辑你的答案
    • 我在使用您的方法时遇到的一个问题是,将searchBartranslatesAutoresizingMaskIntoConstraints 设置为false 导致searchBar 不会出现在屏幕上。省略此行会在屏幕上保留searchBar,但动画仍会出现。
    • 哦,是的,@DavidChopin,如果您设置框架,请不要将 translatesAutoresizingMaskIntoConstraints 设置为 false。我在子类 uiview 中使用此方法和约束,我将其用作视图控制器的视图并调用 loadView,因此我以编程方式执行所有操作,如果您设置框架而不是使用约束,它的工作方式可能会有所不同。
    • 是的,所以我意识到我可能应该在实现您的方法时以编程方式添加UISearchBar,我这样做了。最终将其框架设置为CGRect(x: 0, y: view.safeAreaInsets.top, width: view.frame.width, height: 56)。奇怪的是,仍然没有为我工作。 ://
    • @DavidChopin 让我今晚/明天晚些时候检查一下,我会重新创建你正在做的事情,看看我能不能解决它。多年来,我一直在用 UIsearchbar 解决问题,我知道这方面的感觉,给我 24 小时。这将解决每个讨厌 UISearchBar 的编码员的问题,这对我来说非常有用,但让我展示我的 Swift 肌肉,看看会发生什么变化
    猜你喜欢
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-27
    • 2011-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多