K.Wu
K.Wu

Reputation: 3633

How to add a reusable view without loading from xib in Swift?

Very new to Swift here, thanks for being patient!

Say I want to write a reusable scroll view called ProfileView like so (question is highlighted below):

import UIKit

class ProfileView: UIView, UIScrollViewDelegate {
    var profileView: UIScrollView!
    var profile: Profile!    // Profile is a custom class
                             // It contains user's profile, name, etc

    init (frame: CGRect, profile: Profile) {
        super.init(frame: frame)
        profileScrollView = UIScrollView(frame: frame)
        self.profile = profile
        loadView()
    }

    func loadView() {
        profileScrollView.delegate = self

        // Then go ahead and display user's profile info such as
        // their names and profile pictures etc
    }

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        print("\(scrollView.contentOffset.y)")
    }
}

You might've noticed, ProfileView inherits from UIScrollViewDelegate as well, because I want to do some animation when users scroll. The question is:

How do I add the scroll view to an existing view?

I've tried this in my ViewController:

@IBOutlet var container: UIView!    // "container" is all of "Safe Area"
var profile = <Some object that's not nil>

override func viewDidLoad() {
    super.viewDidLoad()

    container.addSubview(ProfileView(frame: container.frame, profile: profile))
    print("\(container.subviews.debugDescription)")
}

But the scroll view is not shown and the "print" statement prints:

[
 <_UILayoutGuide:      0x7fca15107cf0; frame = (0 0; 0 0);     hidden = YES; layer = <CALayer: 0x60c00003a1c0>>,
 <_UILayoutGuide:      0x7fca1510eb60; frame = (0 0; 0 0);     hidden = YES; layer = <CALayer: 0x60c000037260>>,
 <TestApp.ProfileView: 0x7fca151031e0; frame = (0 0; 414 736); layer = <CALayer: 0x60c000036fc0>>
]

Upvotes: 0

Views: 154

Answers (1)

matt
matt

Reputation: 536027

You say "But the scroll view is not shown". And that is easy to understand; it's because you never show it.

Look at your ProfileView class code. It declares a profileScrollView which is a scroll view, and gives it a frame, and gives it a delegate, but it never puts that scroll view into the interface. You add the ProfileView itself to the interface, but you never add the ProfileView's profileScrollView to the interface.

Somewhere, somehow, you would need to tell some view that is in the interface to addSubview(profileScrollView). But you never do.

Upvotes: 1

Related Questions