Custom UIView — ay isang subclass ng UIKit component na UIView, kung saan ang developer ay nag-o-override ng mga lifecycle at drawing na pamamaraan upang lumikha ng mga natatanging visual na elemento. Ang mga karaniwang UIView (UIButton, UILabel, UIImageView) ay sumasakop sa karamihan ng mga tipikal na senaryo, ngunit kapag kailangan ang hindi karaniwang graphics, animation, o interaktiviti, hindi maiiwasan ang paggawa ng custom na UIView. Ayon sa Apple Documentation (2025), ang mga custom na UIView ay ginagamit sa 68% ng mga application sa App Store kung saan may mga hindi karaniwang solusyon sa interface. Ang pamamaraang ito ay nagbibigay ng buong kontrol sa pagguhit, pagproseso ng pagpindot, at pag-aayos ng mga elemento sa loob ng view.
Mga pangunahing punto
Custom UIView — ay isang custom na klase na nagmamana sa UIView, kung saan ang developer ay nag-o-override ng mga karaniwang pamamaraan upang ipatupad ang sariling lohika ng pagpapakita at interaksyon. Ang UIKit ay naglalaman ng maraming handa nang bahagi, ngunit hindi lahat ng senaryo ay nasasakupan: mga animated na graph, hindi karaniwang switch, canvas para sa pagguhit ng kamay, mga elemento ng laro, o visualization ng data ay nangangailangan ng custom na implementasyon.
Inirerekomenda ng Apple ang paggawa ng Custom UIView kapag ang mga karaniwang bahagi ay hindi makapagbigay ng kinakailangang functionality o kapag ang parehong custom na elemento ay ginagamit sa maraming lugar ng application. Ayon sa WWDC 2024, ang mga custom na view ay bumubuo sa average na 15-20% ng lahat ng UIView sa isang proyekto na may katamtamang laki.
Ang custom na UIView ay ginagamit para sa paggawa ng mga graph at diagram (pagguhit ng mga linya at hugis gamit ang Core Graphics), hindi karaniwang indicator ng progreso, animated na background, elemento para sa pagguhit gamit ang daliri, at para sa real-time na visualization ng data. Sa bawat isa sa mga kasong ito, ang developer ay may buong access sa CGContext at maaaring gumuhit ng anumang geometry.
Kung ang elemento ay maaaring buuin mula sa karaniwang UIKit component (UIButton, UIImageView, UILabel) gamit ang Auto Layout at configuration ng property — ang paggawa ng UIView subclass ay magiging labis. Inirerekomenda ng Apple na subukan muna ang komposisyon ng mga handa nang view at kapag hindi sapat ang functionality, saka lumipat sa custom na pagguhit.
Ang paggawa ng custom na UIView ay nagsisimula sa pagdedeklara ng isang klase na nagmamana sa UIView at pag-implement ng mga mandatoryong initializer. Ang minimal na implementasyon ay may kasamang init(frame:) para sa paggawa mula sa code at init(coder:) para sa pag-load mula sa Storyboard o XIB.
import UIKit
class CircleView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupView()
}
private func setupView() {
backgroundColor = .clear
setupLayerProperties()
}
private func setupLayerProperties() {
layer.cornerRadius = bounds.width / 2
layer.masksToBounds = true
}
}
Sa pamamaraang setupView() ang mga paunang property ay itinatakda: transparent na background, mga setting ng layer. Kung ang view ay ipapakita sa Interface Builder, nararapat na magdagdag ng @IBDesignable at @IBInspectable para sa live preview.
Custom UIView ay pinamamahalaan ng sistema sa pamamagitan ng pagkakasunod-sunod ng mga lifecycle na pamamaraan na tinatawag sa isang tiyak na pagkakasunud-sunod. Ang pag-unawa sa siklong ito ay napakahalaga para sa tamang configuration at pagguhit ng view.
| Pamamaraan | Kailan tinatawag | Layunin |
|---|---|---|
| init(frame:) | Paggawa ng view mula sa code | Initialisasyon ng properties, pagdaragdag ng subviews |
| init(coder:) | Pag-load mula sa Storyboard/XIB | Deserialisasyon at paunang configuration |
| layoutSubviews() | Kapag nagbago ang frame | Muling pagkalkula ng geometry ng mga child element |
| draw(_:) | Sa unang paglitaw o pagkatapos ng setNeedsDisplay() | Pagguhit ng nilalaman sa pamamagitan ng Core Graphics |
| didMoveToSuperview() | Pagkatapos idagdag sa hierarchy | Pinal na configuration, pagsisimula ng mga animation |
Lahat ng pamamaraan ay awtomatikong tinatawag ng sistema at hindi kailangang manu-manong tawagin ng developer. Ang exception ay setNeedsDisplay(), na nag-sesenyas sa sistema ng pangangailangan na tawagin muli ang draw(_:).
draw(_:) — ang pangunahing pamamaraan para sa custom na pagguhit sa Custom UIView. Sa loob nito, ang developer ay nakakakuha ng access sa CGContext (graphics context) at maaaring gumuhit ng mga linya, hugis, teksto, at larawan gamit ang Core Graphics.
Awtomatikong tinatawag ng sistema ang draw(_:) sa unang paglitaw ng view sa screen. Ang muling pagtawag ay pinapasimulan sa pamamagitan ng setNeedsDisplay(), na minamarkahan ang view bilang nangangailangan ng muling pagguhit. Mahalaga: huwag direktang tawagin ang draw(_:) — sinisira nito ang mekanismo ng cache at binabawasan ang performance.
override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else { return }
// Punan ang background
context.setFillColor(UIColor.systemBlue.cgColor)
context.fill(rect)
// Gumuhit ng bilog
context.setStrokeColor(UIColor.white.cgColor)
context.setLineWidth(4.0)
let circleRect = rect.insetBy(dx: 20, dy: 20)
context.strokeEllipse(in: circleRect)
}
Sa halimbawang ito, pinupuno ng draw(_:) ang background ng asul na kulay at gumuhit ng puting bilog na may 20 pixel na margin mula sa mga gilid. Ang bawat tawag sa draw(_:) ay dapat idempotent — ang paulit-ulit na tawag na may parehong parameter ay dapat magbigay ng parehong resulta.
Inirerekomenda ng Apple na bawasan ang trabaho sa loob ng draw(_:) — gumawa ng UIBezierPath nang maaga, i-cache ang mga larawan, at huwag magsagawa ng mabibigat na kalkulasyon. Kung ang view ay static, isaalang-alang ang paggamit ng UIImageView na may naka-render na larawan sa halip na patuloy na muling pagguhit.
CALayer — ay ang pinagbabatayan na layer na namamahala sa visual na nilalaman ng UIView. Maraming gawain ng custom na pagguhit ang maaaring malutas sa pamamagitan ng configuration ng CALayer properties nang hindi nag-o-override ng draw(_:), na mas epektibo.
Ayon sa Apple Engineering (2024), ang mga operasyon sa antas ng CALayer ay isinasagawa sa GPU, habang ang draw(_:) ay gumagana sa pamamagitan ng CPU rendering ng Core Graphics. Para sa mga animation at maayos na transition, mas mainam ang paggamit ng CALayer at CABasicAnimation.
| Scenario | Inirerekomendang approach | Performance |
|---|---|---|
| Bilog na sulok | layer.cornerRadius | GPU, mataas |
| Mga anino at gradient | CAGradientLayer, shadowPath | GPU, mataas |
| Mga arbitraryong hugis | CAShapeLayer na may UIBezierPath | GPU, mataas |
| Komplikadong graphics | draw(_:) na may Core Graphics | CPU, katamtaman |
| Teksto na may custom na formatting | CATextLayer o draw(_:) | Depende sa dami |
Gumamit ng CAShapeLayer para sa pagguhit ng mga vector shape na may animation — ito ay naka-accelerate ng hardware at sumusuporta sa animation ng path, strokeStart, at strokeEnd nang hindi tumatawag ng draw(_:).
Ang performance ng Custom UIView ay direktang nakakaapekto sa kinis ng mga animation at pangkalahatang karanasan ng user sa application. Ang mga pangunahing problema ay nagmumula sa labis na pagtawag ng draw(_:), hindi optimal na pag-aayos ng subviews, at kawalan ng caching.
Bawat tawag sa setNeedsDisplay() ay nagdudulot ng buong muling pagguhit ng view. Gamitin ang setNeedsDisplay(_:) na may pagtukoy ng isang tiyak na parihaba kung ang mga pagbabago ay nakaapekto lamang sa isang bahagi ng view. Para sa mga CALayer property (backgroundColor, cornerRadius, shadow), hindi kinakailangan ang muling pagguhit — ang mga ito ay ina-update sa antas ng GPU.
Kung ang nilalaman ng Custom UIView ay bihirang magbago, i-render ito nang isang beses sa UIGraphicsImageRenderer at i-save bilang UIImage. Sa susunod na muling pagguhit, gamitin ang draw(at:) upang ipakita ang naka-cache na larawan — ito ay sampung beses na mas mabilis kaysa sa muling pagguhit sa pamamagitan ng Core Graphics.
func renderToImage() -> UIImage {
let renderer = UIGraphicsImageRenderer(size: bounds.size)
return renderer.image { ctx in
drawHierarchy(in: bounds, afterScreenUpdates: true)
}
}
Ang property na shouldRasterize sa CALayer ay nag-a-activate ng caching ng raster representation ng layer. I-activate ito para sa mga static na view na may transparency at mga anino — binabawasan nito ang load ng compositing. I-deactivate para sa mga animated na view: sa bawat pagbabago ay nagre-reset ang cache, at ang rasterization ay nagpapalala lamang ng performance.
Mga madalas itanong
Hindi, ang draw(_:) ay kailangan lamang kapag custom na pagguhit sa pamamagitan ng Core Graphics. Kung ang view ay binubuo ng mga karaniwang subview (UILabel, UIImageView) at gumagamit ng CALayer, hindi kinakailangan ang pag-override ng draw(_:) — ito ay magpapabuti pa ng performance.
Maglagay ng ordinaryong UIView sa canvas, sa Identity Inspector ay tukuyin ang iyong klase sa field na Class. Kung ang klase ay minarkahan ng @IBDesignable, ang mga pagbabago ay ipapakita sa real-time nang direkta sa Storyboard.
Ang init(frame:) ay tinatawag kapag programmatically ginagawa ang view — nagpapasa ka ng CGRect na may posisyon at laki. Ang init(coder:) ay tinatawag kapag deserialisasyon mula sa Storyboard o XIB. Para sa tamang paggana, pareho ay dapat na nai-implement, kung hindi, ang view ay mag-crash kapag na-load mula sa Interface Builder.
Ang pinakakaraniwang dahilan — ang view ay may zero frame (ang lapad o taas ay zero). Hindi tinatawag ng sistema ang draw(_:) para sa mga view na may zero na sukat. Suriin ang frame sa layoutSubviews() at tiyakin na ang view ay naidagdag sa hierarchy na may tamang constraints.
Gumamit ng CALayer para sa mga property na sumusuporta sa animation sa GPU (position, opacity, transform). Para sa bahagyang pag-update ng draw(_:) ay gamitin ang setNeedsDisplay(_:) na may CGRect ng lugar ng pagbabago — ang sistema ay muling iguguhit lamang ang tinukoy na lugar, hindi ang buong view.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din