重新加载视图时 UILabel 没有采用适当的框架

UILabel not taking appropriate frame when reloading view

所以我的应用程序的主屏幕有一个汉堡包按钮,可用于导航到应用程序的其他部分。话虽如此,有人可能会在应用程序的其他部分收到通知,因此我尝试添加一个指示器,它只是 UILabel 的子类,显示在汉堡按钮上。当视图第一次加载时,它看起来像这样,这很好:

好的,所以当用户打开导航抽屉时,我将汉堡包按钮设置为动画并通过隐藏它来删除通知 (self.badge.hidden = true),它会正常消失,如下所示:

现在我面临的问题是,当视图重新动画化时,通知标志最终出现在一个非常奇怪的地方,即使没有帧发生变化,如果我打印出帧,它就是在那里它应该以编程方式进行,但实际上它最终看起来真的很奇怪,就像左上角的小气泡一样:

我所做的就是在导航抽屉关闭时在我的委托方法中添加它,我尝试 self.badge.hidden = false。所以很明显这里发生了一些奇怪的事情。

但更奇怪的是,如果我导航到另一个视图,假设我按下导航抽屉中的一个按钮,然后返回主视图,那么隐藏工作正常,当我取消隐藏时通知徽章然后它出现在它应该出现的地方!正如我所说,只有当我离开主屏幕然后返回主屏幕时才会发生这种情况,但是当应用程序首次加载并且我转到导航抽屉时,通知徽章被放在错误的位置并且也非常小.我已经尝试了很多事情来尝试让它发挥作用。最初我是在重新初始化徽章视图之前使用与加载视图时相同的框架将其添加回去,但它仍然以现在的样子结束。我还尝试将它设置为 nil 并将其从 superView 中删除而不是仅仅隐藏它,但是我尝试过的所有不同的事情都导致了同样的事情:在导航到其他地方之前只在主屏幕上,关闭导航抽屉后,徽章不会出现在正确的位置。我可以 post 更多代码或回答您可能有的任何其他问题,但请帮助我,我无法解决这个问题!

这是我在 viewDidAppear 中的初始化代码:

    badge = SwiftBadge(frame: CGRectMake(15, -5, 15, 15))
    menuButton.addSubview(badge!)
    menuButton.bringSubviewToFront(badge!)

并创建我的 menuButton(我在 viewDidLoad 中这样做)

menuButton = UIButton(frame: CGRectMake(0, 0, 20, 20))
menuButton.setBackgroundImage(UIImage(named: "Side menu.png"), forState: .Normal)
let addBarItem = UIBarButtonItem(customView: addButton)
let menuButtonItem = UIBarButtonItem(customView: menuButton)
self.navigationItem.setLeftBarButtonItem(menuButtonItem, animated: true)

编辑 2:

旋转汉堡按钮的代码

let animationDuration = self.revealViewController().toggleAnimationDuration
        UIView.animateWithDuration(animationDuration, animations: { () -> Void in
            if !self.menuButtonRotated {
                //self.badge?.removeFromSuperview()
                self.badge?.hidden = true
                self.menuButton.transform = CGAffineTransformMakeRotation(CGFloat(M_PI_2))
                self.menuButtonRotated = true
                print("Menu frame after rotation: \(self.menuButton.frame)")
            } else {
                self.menuButton.transform = CGAffineTransformMakeRotation(CGFloat(0))
                self.menuButtonRotated = false
                self.badge?.hidden = false
            }
            }, completion: { (bool) -> Void in
                if !self.menuButtonRotated {
                //self.badge = SwiftBadge(frame: CGRectMake(250, 250, 100, 100))
                print("New menu frame: \(self.menuButton.frame)")
                print("New badge frame: \(self.badge!.frame)")
                //self.view.addSubview(self.badge!)
                //self.badge?.hidden = false
            }
    })

注释掉的代码是我尝试过的其他一些东西。

好吧,经过多次调试和纠缠,我终于找到了修复方法。无论出于何种原因,我的 menuButton 帧似乎并没有在动画结束后立即设置,所以我不得不将我的动画代码更改为以下内容,希望这对稍后查看的人有所帮助:

UIView.animateWithDuration(animationDuration, animations: { () -> Void in
            if !self.menuButtonRotated {
                self.badge?.hidden = true
                self.badge?.removeFromSuperview()
                self.badge = nil
                self.menuButton.transform = CGAffineTransformMakeRotation(CGFloat(M_PI_2))
                self.menuButtonRotated = true
                print("Menu frame after rotation: \(self.menuButton.frame)")
            } else {
                self.menuButton.transform = CGAffineTransformMakeRotation(CGFloat(0))
                self.menuButtonRotated = false
            }
            }, completion: { (bool) -> Void in
                if !self.menuButtonRotated {
                    print("New menu frame: \(self.menuButton.frame)")
                    print("New badge frame: \(self.badge?.frame)")
                    let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(0.05 * Double(NSEC_PER_SEC)))
                    dispatch_after(delayTime, dispatch_get_main_queue()) {
                        self.badge = SwiftBadge(frame: CGRectMake(13, -7, 15, 15))
                        self.badge?.alpha = 0.95
                        self.menuButton.addSubview(self.badge!)
                        self.menuButton.layoutIfNeeded()
                    }
            }
})