gpt4 book ai didi

swift - 为什么 UIView.animateWithDuration 不影响这个自定义 View ?

转载 作者:行者123 更新时间:2023-11-28 08:32:03 25 4
gpt4 key购买 nike

我设计了一个自定义标题 View ,它屏蔽了一个图像并在底部边缘绘制了一个边框,这是一个弧形。它看起来像这样:

enter image description here

这是类的代码:

class HeaderView: UIView
{
private let imageView = UIImageView()
private let dimmerView = UIView()

private let arcShape = CAShapeLayer()
private let maskShape = CAShapeLayer() // Masks the image and the dimmer

private let titleLabel = UILabel()

@IBInspectable var image: UIImage? { didSet { self.imageView.image = self.image } }
@IBInspectable var title: String? { didSet {self.titleLabel.text = self.title} }

@IBInspectable var arcHeight: CGFloat? { didSet {self.setupLayers()} }

// MARK: Initialization

override init(frame: CGRect)
{
super.init(frame:frame)
initMyStuff()
}

required init?(coder aDecoder: NSCoder)
{
super.init(coder:aDecoder)
initMyStuff()
}

override func prepareForInterfaceBuilder()
{
backgroundColor = UIColor.clear()
}

internal func initMyStuff()
{
backgroundColor = UIColor.clear()

titleLabel.font = Font.AvenirNext_Bold(24)
titleLabel.text = "TITLE"
titleLabel.textColor = UIColor.white()
titleLabel.layer.shadowColor = UIColor.black().cgColor
titleLabel.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)

titleLabel.layer.shadowRadius = 0.0;
titleLabel.layer.shadowOpacity = 1.0;

titleLabel.layer.masksToBounds = false
titleLabel.layer.shouldRasterize = true

imageView.contentMode = UIViewContentMode.scaleAspectFill
addSubview(imageView)

dimmerView.frame = self.bounds
dimmerView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.6)
addSubview(dimmerView)
addSubview(titleLabel)

// Add the shapes
self.layer.addSublayer(arcShape)
self.layer.addSublayer(maskShape)
self.layer.masksToBounds = true // This seems to be unneeded...test more

// Set constraints
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView .autoPinEdgesToSuperviewEdges()
titleLabel.autoCenterInSuperview()
}

func setupLayers()
{
let aHeight = arcHeight ?? 10

// Create the arc shape
arcShape.path = AppocalypseUI.createHorizontalArcPath(CGPoint(x: 0, y: bounds.size.height), width: bounds.size.width, arcHeight: aHeight)
arcShape.strokeColor = UIColor.white().cgColor
arcShape.lineWidth = 1.0
arcShape.fillColor = UIColor.clear().cgColor

// Create the mask shape
let maskPath = AppocalypseUI.createHorizontalArcPath(CGPoint(x: 0, y: bounds.size.height), width: bounds.size.width, arcHeight: aHeight, closed: true)
maskPath.moveTo(nil, x: bounds.size.width, y: bounds.size.height)
maskPath.addLineTo(nil, x: bounds.size.width, y: 0)
maskPath.addLineTo(nil, x: 0, y: 0)
maskPath.addLineTo(nil, x: 0, y: bounds.size.height)

//let current = CGPathGetCurrentPoint(maskPath);
//print(current)

let mask_Dimmer = CAShapeLayer()
mask_Dimmer.path = maskPath.copy()

maskShape.fillColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1.0).cgColor
maskShape.path = maskPath

// Apply the masks
imageView.layer.mask = maskShape
dimmerView.layer.mask = mask_Dimmer
}

override func layoutSubviews()
{
super.layoutSubviews()

// Let's go old school here...
imageView.frame = self.bounds
dimmerView.frame = self.bounds
setupLayers()
}
}

像这样的事情会导致它只是捕捉到新的大小而不逐渐改变它的框架:

UIView.animate(withDuration: 1.0)
{
self.headerView.arcHeight = self.new_headerView_arcHeight
self.headerView.frame = self.new_headerView_frame
}

我认为这一定与我正在使用 CALayers 这一事实有关,但我对幕后发生的事情并不十分了解。

编辑:这是我用来创建弧形路径的函数:

class func createHorizontalArcPath(_ startPoint:CGPoint, width:CGFloat, arcHeight:CGFloat, closed:Bool = false) -> CGMutablePath
{
// http://www.raywenderlich.com/33193/core-graphics-tutorial-arcs-and-paths

let arcRect = CGRect(x: startPoint.x, y: startPoint.y-arcHeight, width: width, height: arcHeight)

let arcRadius = (arcRect.size.height/2) + (pow(arcRect.size.width, 2) / (8*arcRect.size.height));
let arcCenter = CGPoint(x: arcRect.origin.x + arcRect.size.width/2, y: arcRect.origin.y + arcRadius);

let angle = acos(arcRect.size.width / (2*arcRadius));
let startAngle = CGFloat(M_PI)+angle // (180 degrees + angle)
let endAngle = CGFloat(M_PI*2)-angle // (360 degrees - angle)
// let startAngle = radians(180) + angle;
// let endAngle = radians(360) - angle;

let path = CGMutablePath();
path.addArc(nil, x: arcCenter.x, y: arcCenter.y, radius: arcRadius, startAngle: startAngle, endAngle: endAngle, clockwise: false);
if(closed == true)
{path.addLineTo(nil, x: startPoint.x, y: startPoint.y);}
return path;
}

奖金:将 arcHeight 属性设置为 0 会导致不绘制白线。为什么?

最佳答案

Path 属性无法设置动画。你必须以不同的方式处理问题。您可以“立即”绘制弧线,任何弧线,这样就告诉我们需要手动处理动画。如果您预计整个绘制过程需要 3 秒,那么您可能希望将该过程拆分为 1000 个部分,并每 0.3 毫秒调用 1000 次圆弧绘制函数以从起点到当前点再次绘制圆弧。

关于swift - 为什么 UIView.animateWithDuration 不影响这个自定义 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38655001/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com