Articles

Subklass av anpassad UIView från en xib-fil

Anpassade vyer med utlopp & åtgärder

Det korrekta sättet att ladda anpassade vyer från xib-filer går ungefär så här:

I ditt objekt för anpassad vy instansierar du xib-filen på exakt samma sätt som jag berättade för dig här uppe. 👆 Den enda skillnaden är att du inte behöver använda objektmatrisen som returneras av metoderna, utan du måste ansluta dina visningsobjekt via gränssnittsbyggaren, genom att använda Filens ägare som referenspunkt, plus en anpassad behållarvisningsutgång, som kommer att innehålla allt du behöver. 🤨

// note: view object is from my previous tutorial, with autoresizing masks disabledclass CustomView: View { // this is going to be our container object @IBOutlet weak var containerView: UIView! // other usual outlets @IBOutlet weak var textLabel: UILabel! override func initialize() { super.initialize() // first: load the view hierarchy to get proper outlets let name = String(describing: type(of: self)) let nib = UINib(nibName: name, bundle: .main) nib.instantiate(withOwner: self, options: nil) // next: append the container to our view self.addSubview(self.containerView) self.containerView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate() }}

Så initialiseringsmetoden här laddar bara nib-filen med ägaren self. När laddningsprocessen är klar kommer dina utloppsmarkörer att fyllas med korrekta värden från xib-filen. Det finns en sista sak som vi måste göra. Även vyerna från xib-filen är ”programmatiskt” anslutna till vårt anpassade vyobjekt, men visuellt är de inte det. Så vi måste lägga till vår containervy i vyhierarkin. 🤐

Om du vill använda ditt anpassade vyobjekt behöver du bara skapa en ny instans av det – inne i en vykontrollant – och till sist får du gärna lägga till det som en undervy!

Ett ord om bounds, frames aka. springs och struts: f*ckng UGLY! Det är två ord. De anses vara en dålig praxis, så använd gärna automatisk layout, jag har en trevlig handledning om ankare, de är fantastiska och att lära sig dem tar ungefär 15 minuter. 😅

class ViewController: UIViewController { weak var customView: CustomView! override func loadView() { super.loadView() let customView = CustomView() self.view.addSubview(customView) NSLayoutConstraint.activate() self.customView = customView } override func viewDidLoad() { super.viewDidLoad() self.customView.textLabel.text = "Lorem ipsum" }}

Det var allt, nu har du ett helt fungerande anpassat UIView-objekt som laddar en xib-fil för att använda dess innehåll. Det var väl inte så illa, eller hur? 🤪

En extra sak till. Om du inte gillar att hantera vyer programmatiskt eller om du helt enkelt inte vill krångla med loadView-metoden är det bara att ta bort den helt och hållet. Sätt sedan nyckelordet @IBOutlet precis före din anpassade klassvariabel för vyer. Öppna din storyboard med IB, dra & släpp sedan ett nytt UIView-element till din controller och anslut den anpassade vyutgången. Det borde fungera som magi. 💫

Jag lovade outlets och åtgärder i rubriken för det här avsnittet, så låt oss prata lite om IBActions. De fungerar precis på samma sätt som du förväntar dig att de ska göra med controllers. Du kan helt enkelt koppla en knapp till din anpassade vy och delegera åtgärden till den anpassade vyklassen. Om du vill vidarebefordra beröringar eller specifika åtgärder till en kontrollant bör du använda delegeringsmönstret eller välja ett enkelt block. 😎