两个连接的看法差距 - 自动布局和UIViewAnimation [英] Auto layout and UIViewAnimation - Gap between two connected views
问题描述
我创建了一个提示的观点有一个UILabel和一个三角形状的CAShapeLayer一个UIView的。
我已经设置了工具提示,使该标签是在上面,与三角形连接于底部并集中在的UILabel
I created a "tooltip" view that has a UILabel and an UIView with a CAShapeLayer for a triangle shape. I have setup the "tooltip" so that the label is on top, with the triangle attached to the bottom and centered on the UILabel.
当我展示提示,我用弹簧减震和Spring速度的UIViewAnimation给它一个啪的动画。这有一个例外的伟大工程,一个小缺口可以在三角形和动画的开始期间的UILabel(间注意到,当动画结束,然后固定。
When I show the "tooltip", I use the UIViewAnimation with Spring Damping and Spring Velocity to give it a "pop" animation. This works great with one exception, a small gap can be noticed between the triangle and the UILabel during the beginning of the animation (which is then fixed when the animation ends.
这是如何解决这一问题有什么建议?
Any suggestions on how to fix this?
这里是查看/约束设置:
let containerView = UIView()
containerView.alpha = 1.0
containerView.layer.cornerRadius = 5.0
containerView.clipsToBounds = true
containerView.backgroundColor = UIColor.orangeColor()
self.addSubview(containerView)
self.containerView = containerView
let titleLabel = UILabel()
titleLabel.font = UIFont.systemFontOfSize(14.0)
titleLabel.textColor = UIColor.whiteColor()
titleLabel.numberOfLines = 0
titleLabel.adjustsFontSizeToFitWidth = true
containerView.addSubview(titleLabel)
self.titleLabel = titleLabel
let triangleView = UIView()
self.addSubview(triangleView)
self.triangleView = triangleView
let views: [String: UIView] = [
"containerView" : containerView,
"titleLabel" : titleLabel,
"triangleView" : triangleView,
]
let metrics = [String:AnyObject]()
for (_, view) in views {
view.translatesAutoresizingMaskIntoConstraints = false
}
NSLayoutConstraint.activateConstraints(NSLayoutConstraint.constraintsWithVisualFormat("|-8-[titleLabel]-8-|", options: [], metrics: metrics, views: views))
NSLayoutConstraint.activateConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-8-[titleLabel]-8-|", options: [], metrics: metrics, views: views))
let widthConstraint = NSLayoutConstraint(item: self, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 0)
widthConstraint.active = true
self.widthConstraint = widthConstraint
let heightConstraint = NSLayoutConstraint(item: self, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 0)
heightConstraint.active = true
self.heightConstraint = heightConstraint
let trianglePath = UIBezierPath()
trianglePath.moveToPoint(CGPoint(x: 0, y: 0))
trianglePath.addLineToPoint(CGPoint(x: 8.0, y: 10.0))
trianglePath.addLineToPoint(CGPoint(x: 16.0, y: 0))
trianglePath.closePath()
let mask = CAShapeLayer()
mask.frame = triangleView.bounds
mask.path = trianglePath.CGPath
triangleView.layer.mask = mask
NSLayoutConstraint.activateConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[containerView][triangleView]|", options: [], metrics: metrics, views: views))
NSLayoutConstraint.activateConstraints(NSLayoutConstraint.constraintsWithVisualFormat("|[containerView]|", options: [], metrics: metrics, views: views))
NSLayoutConstraint.activateConstraints(NSLayoutConstraint.constraintsWithVisualFormat("|-(>=8)-[self]-(>=8)-|", options: [], metrics: metrics, views: views))
NSLayoutConstraint.activateConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-(>=8)-[self][anchorView]", options: [], metrics: metrics, views: views))
NSLayoutConstraint.activateConstraints(NSLayoutConstraint.constraintsWithVisualFormat("[triangleView(>=16)]", options: [], metrics: metrics, views: views))
NSLayoutConstraint.activateConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[triangleView(>=10)]", options: [], metrics: metrics, views: views))
NSLayoutConstraint(item: self.triangleView, attribute: .CenterX, relatedBy: .Equal, toItem: self.anchorView, attribute: .CenterX, multiplier: 1.0, constant: 1.0).active = true
let centerXConstraint = NSLayoutConstraint(item: triangleView, attribute: .CenterX, relatedBy: .Equal, toItem: containerView, attribute: .CenterX, multiplier: 1.0, constant: 0.0)
centerXConstraint.priority = UILayoutPriorityDefaultLow // Required to allow tooltip to grow beyond anchorView bounds without changing the anchorView constraints.
centerXConstraint.active = true
这里是动画脚本:
self.layoutIfNeeded() // Set starting position for tooltip before animation
self.widthConstraint.active = false
self.heightConstraint.active = false
UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.5, options: .CurveEaseInOut, animations: { () -> Void in
self.alpha = 1.0
self.layoutIfNeeded()
}, completion: nil)
推荐答案
接近这将是有一个自定义的UILabel单程
One way to approach it would be to have a custom UILabel
class ToolTip: UILabel {
var roundRect:CGRect!
override func drawTextInRect(rect: CGRect) {
super.drawTextInRect(roundRect)
}
override func drawRect(rect: CGRect) {
roundRect = CGRect(x: rect.minX, y: rect.minY, width: rect.width, height: rect.height * 4 / 5)
let roundRectBez = UIBezierPath(roundedRect: roundRect, cornerRadius: 10.0)
let triangleBez = UIBezierPath()
triangleBez.moveToPoint(CGPoint(x: roundRect.minX + roundRect.width / 2.5, y:roundRect.maxY))
triangleBez.addLineToPoint(CGPoint(x:rect.midX,y:rect.maxY))
triangleBez.addLineToPoint(CGPoint(x: roundRect.maxX - roundRect.width / 2.5, y:roundRect.maxY))
triangleBez.closePath()
roundRectBez.appendPath(triangleBez)
let bez = roundRectBez
UIColor.lightGrayColor().setFill()
bez.fill()
super.drawRect(rect)
}
}
,然后执行布局和动画像这样:
and then perform layout and animation like so:
import UIKit
class ViewController: UIViewController {
var label:ToolTip!
var labelTransform:CGAffineTransform!
let buttonHeight:CGFloat = 100
let buttonWidth:CGFloat = 200
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton()
button.setTitle("Push Me", forState: .Normal)
button.addTarget(self, action: Selector("buttonPushed"), forControlEvents: .TouchUpInside)
button.backgroundColor = UIColor.orangeColor()
view.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
button.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor).active = true
button.centerYAnchor.constraintEqualToAnchor(view.centerYAnchor).active = true
button.heightAnchor.constraintEqualToConstant(buttonHeight).active = true
button.widthAnchor.constraintEqualToConstant(buttonWidth).active = true
label = ToolTip()
view.insertSubview(label, belowSubview: button)
label.translatesAutoresizingMaskIntoConstraints = false
label.heightAnchor.constraintEqualToConstant(buttonHeight).active = true
label.widthAnchor.constraintEqualToConstant(buttonWidth).active = true
label.bottomAnchor.constraintEqualToAnchor(button.topAnchor).active = true
label.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor).active = true
label.text = "This button is orange!"
label.textColor = UIColor.whiteColor()
label.textAlignment = .Center
let trans1 = CGAffineTransformMakeScale(0, 0)
let trans2 = CGAffineTransformMakeTranslation(0, buttonHeight)
labelTransform = CGAffineTransformConcat(trans1, trans2)
label.transform = labelTransform
}
func buttonPushed() {
if label.transform.ty > 0 {
UIView.animateWithDuration(0.75, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.5, options: .CurveEaseInOut, animations: { () -> Void in
self.label.transform = CGAffineTransformIdentity
}, completion: nil)
}
else {
UIView.animateWithDuration(0.5, delay: 0, options: .CurveEaseInOut, animations: { () -> Void in
self.label.alpha = 0
}, completion: {_ in
self.label.transform = self.labelTransform
self.label.alpha = 1
}) }
}
}
它创建后续效果:
which creates the follow effect:
这篇关于两个连接的看法差距 - 自动布局和UIViewAnimation的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!