ฉันมีชั้นย่อยที่เพิ่มเข้ามาในเลเยอร์UIView
ประมาณ 8 CALayer
ชั้น ถ้าผมปรับเปลี่ยนมุมมองขอบเขตของ (animated) แล้วมุมมองของตัวเองหดตัว (ฉันจะตรวจสอบด้วยbackgroundColor
) แต่ขนาด sublayers' ยังคงไม่เปลี่ยนแปลง
วิธีแก้ปัญหานี้?
ฉันมีชั้นย่อยที่เพิ่มเข้ามาในเลเยอร์UIView
ประมาณ 8 CALayer
ชั้น ถ้าผมปรับเปลี่ยนมุมมองขอบเขตของ (animated) แล้วมุมมองของตัวเองหดตัว (ฉันจะตรวจสอบด้วยbackgroundColor
) แต่ขนาด sublayers' ยังคงไม่เปลี่ยนแปลง
วิธีแก้ปัญหานี้?
คำตอบ:
ฉันใช้วิธีเดียวกับที่ Solin ใช้ แต่มีการพิมพ์ผิดในรหัสนั้น วิธีการควรเป็น:
- (void)layoutSubviews {
[super layoutSubviews];
// resize your layers based on the view's new bounds
mylayer.frame = self.bounds;
}
สำหรับจุดประสงค์ของฉันฉันต้องการให้ชั้นย่อยมีขนาดเต็มของมุมมองพาเรนต์เสมอ ใส่วิธีนั้นในคลาสมุมมองของคุณ
UITextView
(scrollEnabled = NO) และรูปแบบอัตโนมัติ ฉันมีมุมมองข้อความที่ตรึงไว้ที่ superview ซึ่งจะมีCALayer
ที่ด้านล่างของตัวมันเอง (เส้นขอบ) และฉันต้องการให้มันอัปเดตตำแหน่งเส้นขอบเมื่อความสูงของมุมมองข้อความเปลี่ยนไป ด้วยเหตุผลบางอย่างlayoutSubiews
เรียกว่าสายเกินไป (และตำแหน่งเลเยอร์เป็นภาพเคลื่อนไหว)
เนื่องจาก CALayer บน iPhone ไม่รองรับตัวจัดการเลย์เอาต์ฉันคิดว่าคุณต้องทำให้เลเยอร์หลักของมุมมองของคุณเป็นคลาสย่อยของ CALayer ที่กำหนดเองซึ่งคุณจะแทนที่layoutSublayers
เพื่อตั้งค่าเฟรมของเลเยอร์ย่อยทั้งหมด คุณต้องลบล้าง+layerClass
เมธอดของมุมมองของคุณด้วยเพื่อส่งคืนคลาสของคลาสย่อย CALayer ใหม่ของคุณ
ฉันใช้สิ่งนี้ใน UIView
-(void)layoutSublayersOfLayer:(CALayer *)layer
{
if (layer == self.layer)
{
_anySubLayer.frame = layer.bounds;
}
super.layoutSublayersOfLayer(layer)
}
ใช้ได้ผลสำหรับฉัน
CALayerDelegate
's draw(_:in:)
) _anySubLayer.setNeedsDisplay()
ผมต้องยังโทร จากนั้นสิ่งนี้ก็ใช้ได้ผลสำหรับฉัน
ผมมีปัญหาเหมือนกัน. ในเลเยอร์ของมุมมองแบบกำหนดเองฉันได้เพิ่มเลเยอร์ย่อยอีกสองชั้น ในการปรับขนาดเลเยอร์ย่อย (ทุกครั้งที่ขอบเขตของมุมมองที่กำหนดเองเปลี่ยนไป) ฉันใช้วิธีนี้layoutSubviews
ของมุมมองที่กำหนดเองของฉัน ในวิธีนี้ฉันเพิ่งอัปเดตเฟรมของแต่ละชั้นย่อยให้ตรงกับขอบเขตปัจจุบันของเลเยอร์มุมมองย่อยของฉัน
สิ่งนี้:
-(void)layoutSubviews{
//keep the same origin, just update the width and height
if(sublayer1!=nil){
sublayer1.frame = self.layer.bounds;
}
}
คำตอบที่แท้จริงสำหรับคำถามนี้:
จะดีขึ้นหรือแย่ลง
needsDisplayOnBoundsChange
CALayer
ค่าเริ่มต้นในการเท็จ
สารละลาย,
class CircularGradientViewLayer: CALayer {
override init() {
super.init()
needsDisplayOnBoundsChange = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override open func draw(in ctx: CGContext) {
go crazy drawing in .bounds
}
}
แน่นอนฉันแนะนำคุณไปยัง QA นี้
https://stackoverflow.com/a/47760444/294884
ซึ่งอธิบายว่าการcontentsScale
ตั้งค่าวิกฤตทำอะไร โดยปกติคุณจะต้องตั้งค่าให้เท่า ๆ กันเมื่อคุณตั้งค่า needsDisplayOnBoundsChange
เวอร์ชัน Swift 3
ในเซลล์แบบกำหนดเองเพิ่มบรรทัดต่อไปนี้
ประกาศก่อน
let gradientLayer: CAGradientLayer = CAGradientLayer()
จากนั้นเพิ่มบรรทัดต่อไปนี้
override func layoutSubviews() {
gradientLayer.frame = self.YourCustomView.bounds
}
ตามที่ [Ole] เขียนว่า CALayer ไม่รองรับการปรับอัตโนมัติบน iOS ดังนั้นคุณควรปรับเค้าโครงด้วยตนเอง ตัวเลือกของฉันคือปรับเฟรมของเลเยอร์ภายใน (iOS 7 และรุ่นก่อนหน้า)
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
หรือ (ตั้งแต่ iOS 8)
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinato
ในมุมมองที่กำหนดเองคุณต้องประกาศตัวแปรสำหรับเลเยอร์ที่กำหนดเองของคุณอย่าประกาศตัวแปรในขอบเขตการเริ่มต้น และเริ่มต้นเพียงครั้งเดียวอย่าพยายามตั้งค่าว่างและเริ่มต้นใหม่
คลาส CustomView: UIView { var customLayer: CALayer = CALayer () แทนที่เค้าโครง funcSubviews () { super.layoutSubviews () // guard let _fillColor = self._fillColor else {return} initializeLayout () } func ส่วนตัว initializeLayout () { customLayer.removeFromSuperView () customLayer.frame = layer.bounds layer.insertSubview (ที่: 0) } }