Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ComponentDelegate is nil #836

Open
iAlirezaKML opened this issue Mar 20, 2018 · 3 comments
Open

ComponentDelegate is nil #836

iAlirezaKML opened this issue Mar 20, 2018 · 3 comments

Comments

@iAlirezaKML
Copy link

The function func component(_ component: Component, itemSelected item: Item) is not get called, since the component.delegate in line 65 of Delegate+iOS+Extensions.swift is nil.

@zenangst
Copy link
Owner

Hey @iAlirezaKML, mind sharing some more information about your implementation?
Do you use standalone components or do you have a controller-centric setup? And at what time do you set your delegate?

@iAlirezaKML
Copy link
Author

Hi @zenangst, of course, here's an implementation:

import UIKit
import Spots


enum KBComponentKind: String, StringConvertible {
  var string: String {
    return rawValue
  }
  
  case contactView
}


class ContactView: UIView {
  let titleLabel: UILabel = {
    let label = UILabel.init()
    label.textAlignment = .center
    label.textColor = .gray
    return label
  }()
  
  override init(frame: CGRect) {
    super.init(frame: frame)

    addSubview(titleLabel)
  }
  
  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
  
  override func layoutSubviews() {
    super.layoutSubviews()
    
    titleLabel.frame = frame
  }
}

extension ContactView: ItemConfigurable {
  func configure(with item: Item) {
    titleLabel.text = item.title
  }
  
  func computeSize(for item: Item, containerSize: CGSize) -> CGSize {
    return CGSize.init(width: containerSize.width,
                       height: 44)
  }
}


class Delegator: NSObject {}

extension Delegator: ComponentDelegate {
  func component(_ component: Component, itemSelected item: Item) {
    print(#function) // not called!!!
    print(component, item)
  }
  
  func component(_ component: Component, willDisplay view: ComponentView, item: Item) {
    print(#function) // called!
    if item.kind == KBComponentKind.contactView.rawValue {
      view.transform = CGAffineTransform.init(scaleX: 0.01, y: 0.01)
      view.alpha = 0
      UIView.animate(withDuration: 0.8, delay: 0.1, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.3, options: [.curveEaseOut], animations: {
        view.alpha = 1
        view.transform = CGAffineTransform.identity
      }, completion: nil)
    }
  }
  
  func component(_ component: Component, didEndDisplaying view: ComponentView, item: Item) {
    print(#function) // called!
  }
}


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

  var window: UIWindow?
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    let window = UIWindow.init(frame: UIScreen.main.bounds)
    self.window = window

    Configuration.shared.register(view: ContactView.self, identifier: KBComponentKind.contactView)
    Configuration.shared.registerDefault(view: ContactView.self)
    let model = ComponentModel.init(
      kind: .grid,
      layout: Layout.init(span: 3,
                          dynamicSpan: false,
                          dynamicHeight: false,
                          itemsPerRow: 3,
                          itemSpacing: 1,
                          lineSpacing: 1,
                          inset: Inset.init(padding: 12),
                          showEmptyComponent: false,
                          infiniteScrolling: false),
      items: [
        Item(title: "Sindre Moen", kind: "contactView"),
        Item(title: "Torgeir Øverland", kind: "contactView"),
        Item(title: "Francesco Rodriguez", kind: "contactView"),
        Item(title: "Henriette Røseth", kind: "contactView"),
        Item(title: "Peter Sergeev", kind: "contactView"),
        Item(title: "John Terje Sirevåg", kind: "contactView"),
        Item(title: "Chang Xiangzhong", kind: "contactView")
      ]
    )
    let component = Component.init(model: model)
    let controller = SpotsController.init(components: [component])
    let delegator = Delegator.init()
    controller.delegate = delegator

    window.rootViewController
    window.makeKeyAndVisible()

    return true
  }
}

@iAlirezaKML
Copy link
Author

iAlirezaKML commented Mar 20, 2018

I've got the problem, since in my implementation there is no strong references hold for delegator object, and spots just holds a weak reference to the component delegate, after components are being created, the delegator is not being referenced by any strong variable and it's being pulled out of memory.

Fixed it by holding an strong reference in AppDelegate.

P.S.: Please update the documentation, there are a ton of changes made and has not been reflected to the docs. By the way live editing doesn't work and gets compile errors.

Another question: how can I access to the selected view inside of component(_ component: Component, itemSelected item: Item) to animate on selection?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants