draw(_:) / drawRect — ito ang metodo ng UIView class (sa Swift) at ang katumbas nito sa Objective-C (drawRect:), na responsable sa pag-render ng nilalaman ng view gamit ang Core Graphics. Awtomatikong tinatawag ng system ang metodong ito sa unang paglitaw ng view sa screen at pagkatapos ng pagtawag sa setNeedsDisplay(). Ayon sa Apple Documentation (2025), ang draw(_:) ay ang tanging metodo kung saan ang developer ay may access sa graphic context ng kasalukuyang screen para sa custom na pagguhit. Ang pag-override ng draw(_:) ay nagbibigay ng buong kontrol sa hitsura ng component — mula sa simpleng geometric na hugis hanggang sa kumplikadong animated na graphics.
Mga Pangunahing Punto
draw(_:) — ay isang instance method ng UIView na tinatawag ng UIKit para i-render ang nilalaman ng view. Sa loob ng metodong ito, ang developer ay nakakakuha ng access sa graphic context na CGContext at ginagamit ang Core Graphics API para gumuhit ng mga linya, fill, text, at mga imahe. Ang drawRect: sa Objective-C ay gumagawa ng parehong function, ngunit may ibang syntax: ang tanging parameter ay CGRect na tumutukoy sa area na muling iguguhit.
Ayon sa Apple Engineering (2024), ang draw(_:) ay gumagana sa pamamagitan ng CPU-rendering Bitmap Graphics Context, na nagbibigay ng maximum na flexibility, ngunit nangangailangan ng mas maraming resources kumpara sa CALayer. Ang desisyon na gamitin ang draw(_:) ay ginagawa batay sa pagiging kumplikado ng graphics at mga kinakailangan sa performance.
Sa Swift, ang metodo ay idineklara bilang override func draw(_ rect: CGRect), kung saan ang rect ay ang rectangle na kailangang muling iguhit. Sa Objective-C ang signature ay - (void)drawRect:(CGRect)rect. Ang parameter na rect ay maaaring mas maliit kaysa sa bounds ng view sa bahagyang muling pagguhit sa pamamagitan ng setNeedsDisplay(_:).
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextFillRect(context, rect);
}
Awtomatikong tinatawag ng system ang draw(_:) sa mahigpit na tinukoy na mga senaryo. Ang pag-unawa sa mga trigger na ito ay tumutulong upang maiwasan ang hindi kinakailangang muling pagguhit at i-optimize ang performance ng view. Sa ibaba ay nakalista ang lahat ng kaso ng awtomatikong pagtawag ng metodo.
Ang dokumentasyon ng Apple ay nagbabala: huwag kailanman tawagin nang direkta ang draw(_:). Ang system mismo ang nagpapasya kung kailan isasagawa ang pagguhit, at ang direktang pagtawag ay sumisira sa internal caching mechanism. Para humiling ng muling pagguhit, palaging gamitin ang setNeedsDisplay() o setNeedsDisplay(_:).
Ang pag-override ng draw(_:) sa Swift ay nagsisimula sa pagkuha ng graphic context at mga sumusunod na pagtawag sa Core Graphics. Inirerekomenda na gumawa ng hiwalay na mga metodo para sa logical na bloke ng pagguhit — pinapabuti nito ang pagiging madaling basahin at testability ng code.
override func draw(_ rect: CGRect) {
super.draw(rect)
guard let context = UIGraphicsGetCurrentContext() else { return }
// Mga parameter ng linya
context.setStrokeColor(UIColor.darkGray.cgColor)
context.setLineWidth(2.0)
// Pagguhit ng tatsulok
context.move(to: CGPoint(x: rect.midX, y: rect.minY + 10))
context.addLine(to: CGPoint(x: rect.maxX - 10, y: rect.maxY - 10))
context.addLine(to: CGPoint(x: rect.minX + 10, y: rect.maxY - 10))
context.closePath()
context.strokePath()
}
Sa halimbawang ito, ang draw(_:) ay gumuhit ng tatsulok na may dark gray na outline na 2 pixels ang kapal. Ang pagtawag sa super.draw(rect) sa simula ng metodo ay inirerekomenda ng Apple upang mapanatili ang parent drawing logic, kahit na ang default na implementasyon ng draw(_:) sa UIView ay walang laman.
Ang bawat pagtawag sa draw(_:) ay dapat magbigay ng magkaparehong resulta sa parehong input data. Ito ay nagpapahintulot sa system na i-cache ang resulta at hindi na tawagin muli ang draw(_:) kung ang nilalaman ng view ay hindi nagbago. Huwag gamitin sa loob ng draw(_:) ang random na halaga, oras ng system, o network requests.
drawRect: — historikal na unang bersyon ng metodo, lumitaw sa iOS 2.0 kasama ng Objective-C. Sa Swift, ang metodo ay pinalitan ng pangalan sa draw(_:) na may paggamit ng external parameter na _. Functional na magkapareho ang mga metodo: pareho silang tumatanggap ng CGRect ng area na muling iguguhit at ginagamit ang UIGraphicsGetCurrentContext() para ma-access ang graphic context.
| Katangian | draw(_:) (Swift) | drawRect: (Objective-C) |
|---|---|---|
| Signature | override func draw(_ rect: CGRect) | - (void)drawRect:(CGRect)rect |
| Pagtawag ng super | super.draw(rect) | [super drawRect:rect] |
| Context | UIGraphicsGetCurrentContext() | UIGraphicsGetCurrentContext() |
| Parameter rect | rect: CGRect | CGRect rect |
| Performance | Magkapareho | Magkapareho |
Sa pag-migrate ng proyekto mula Objective-C patungong Swift, ang pagpapalit ng pangalan ng metodo ay isa sa mga unang gawain. Ang Xcode ay nagbibigay ng automatic converter, ngunit ang drawRect: ay nangangailangan ng manual na pag-update sa draw(_:). Ayon sa Apple (2024), ang Swift version na draw(_:) ay mas gusto para sa mga bagong proyekto.
Ang draw(_:) ay isinasagawa sa CPU, at ang hindi optimal na implementasyon ay maaaring maging sanhi ng pagbaba ng frame at mababang performance. Ang Apple ay nagre-rekomenda ng ilang napatunayang approach para mapabilis ang pagguhit.
Ang bawat operasyon ng Core Graphics (move(to:), addLine(to:), strokePath) ay may overhead. I-grupo ang mga operasyon at gamitin ang CGPath para sa kumplikadong mga hugis — ang path ay ginagawa nang isang beses at ginagamit muli sa bawat pagtawag ng draw(_:).
UIBezierPath — ay isang Objective-C wrapper sa paligid ng CGPath na nagbibigay ng simpleng API para sa paggawa ng mga hugis. Gumawa ng UIBezierPath nang maaga (hal. sa initializer) at tawagin lamang ang fill() o stroke() sa loob ng draw(_:).
private let starPath: UIBezierPath = {
let path = UIBezierPath()
// Pagbuo ng hugis bituin
path.move(to: CGPoint(x: 50, y: 0))
for i in 1...5 {
let angle = CGFloat(i) * 4 * CGFloat.pi / 5
path.addLine(to: CGPoint(x: 50 + 40 * cos(angle),
y: 50 + 40 * sin(angle)))
}
path.close()
return path
}()
override func draw(_ rect: CGRect) {
UIColor.systemYellow.setFill()
starPath.fill()
}
Ang mga developer ay madalas na gumagawa ng parehong pagkakamali sa pag-override ng draw(_:). Ang kaalaman sa mga pattern na ito ay tumutulong upang maiwasan ang mga bug at pagbaba ng performance. Tingnan natin ang mga pinakakaraniwang problema at ang kanilang mga solusyon.
Sa pagsunod sa mga panuntunang ito, masisiguro mo ang matatag at mabilis na pagguhit ng custom na views sa anumang iOS project. I-profile ang draw(_:) sa pamamagitan ng Instruments (Core Animation) upang makita ang aktwal na oras ng execution at mga bottleneck.
Mga Madalas Itanong
Hindi, ang direktang pagtawag sa draw(_:) ay ipinagbabawal ng dokumentasyon ng Apple. Ang system mismo ang namamahala sa drawing cycle. Para humiling ng muling pagguhit, gamitin ang setNeedsDisplay(), na wastong nagmamarka ng view bilang nangangailangan ng update sa pinakamalapit na rendering cycle.
Functional na magkapareho ang mga metodong ito. Ang drawRect: ay ginagamit sa Objective-C, ang draw(_:) — sa Swift. Pareho silang tumatanggap ng CGRect ng muling pagguhit na area at gumagamit ng parehong Core Graphics context sa pamamagitan ng UIGraphicsGetCurrentContext().
Ino-optimize ng Apple ang rendering: kung ang UIView ay walang naka-override na draw(_:), hindi gumagawa ang system ng bitmap context para dito. Ito ay nakakatipid ng memory. Kung mayroong override ngunit hindi tinatawag ang metodo — suriin na ang frame ng view ay hindi zero at ang view ay nakikita.
Kapag kailangan lamang: unang rendering, pagkatapos ng setNeedsDisplay(), kapag nagbago ang bounds na may contentMode = .redraw. Sa static na estado, hindi na muling tinatawag ang draw(_:), na nakakatipid ng CPU at baterya.
Inirerekomenda ng Apple na tawagin ang super.draw(rect) sa simula ng naka-override na metodo. Kahit na ang kasalukuyang implementasyon ng UIView ay walang laman, ang super call ay nagsisiguro ng compatibility sa hinaharap na bersyon ng UIKit at ito ay mabuting kasanayan.
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