Open angelacaq opened 3 years ago
I liked to consider delegates as instances in when I want to speak "upwards." Two cases are:
1/ MVC: [similar example as Model <-> Views header] I have a generic view that contains a button. What the button does is different depending on the view controller (VC) that initializes the view. I create a delegate in the view. VC1 and VC2 contain the view. In the VCs, I conform to the delegate protocol and create the delegate method. The logic in the delegate method for VC1 can be different from that of VC2; that is, what happens when the button is tapped is personalized by VC.
2/ View Controller <-> View Controller: I have VC1 that segues to VC2. In VC2, something happens that I want to impact VC1. I create a delegate in VC2, and in VC1, I conform to the delegate protocol by creating the delegate method. Now, In VC2, I can call [self.delegate doSomethingWithThisString:(NSString*)thisString]
, and VC1 will implement - (void)doSomethingWithThisString:(NSString *)thisString]
and do whatever it needs to with thisString.
What I mean by speaking "upwards": In example 1, the VC creates the view (VC -> view), and delegates are used to communicate from the view back to the VC (VC <- view). In example 2, VC1 segues to VC2 (VC1 -> VC2), and delegates are used to communicate from VC2 back to VC1 (VC1 <- VC2).
Most of my feedback will revolve around the model-view-controller, the architecture design generally used in iOS. In essence:
Models can be seen as objects (e.g. a Tweet) that has methods that handles state changes (e.g. a Tweet is favorited). Views don't handle logic involving data changes, but rather just displays those changes — which they get from the VC.
Hopefully this will also help a bit with understanding how to implement an APIManager (which essentially was a model in Flix)
Model <-> Views
https://github.com/mary-jiang/FBUTwitter/blob/618bd9895559591ac234705f3144798dcd311040/twitter/Views/TweetCell.m#L31-L64
didTapFavorite
anddidTapRetweet
logic can be moved to the Tweet model, such that you can call[tweet favorite]
and[tweet retweet]
. TweetCell is a view, such that in MVC, it handles UI updates (i.e. setting the content of the labels).In this case, because the purpose of the TweetCell is specifically meant to present the Tweet model (and not to be reused), you don't need to separate out the model from the view.
However, if this wasn't a TweetCell but rather a TweetView that is reused (e.g. in DetailsViewController), then you'd want to completely separate the models/views. In that case, you could create a delegate in the view, call the delegate method in
didTapFavorite
(e.g.[self.delegate didTapFavorite]
) and have the view controller conform to the delegate's protocol and call[tweet favorite]
. That way, the tweet cell view is in complete isolation from model changes.This might feel extra right now, but as you might start reusing views and/or what you can do to a tweet expands, the separation of the three keeps code clean and organized.
View Controllers <-> Views
https://github.com/mary-jiang/FBUTwitter/blob/618bd9895559591ac234705f3144798dcd311040/twitter/View%20Controllers/DetailsViewController.m#L100-L137
A nice thing about having the logic moved to the Tweet model is that you can use it across VCs 😎 (i.e. no repeated code for favoriting/retweeting)
Here, it looks like you are using the view controller as a view too. By the way things work @ FB, the views are generally isolated no matter what (even if it's potentially only used in one place). In this case, you'd want to create a DetailsView.h/.m. You could initialize the view with
And when making updates, refreshing using custom methods like
Basically, considering the view as a separate "template" of sorts, and the VC fills the template.
FWIW, I'm not sure how the custom views end up looking like on Storyboard, but I believe you change the class of main UIView already attached to the UIViewController
If any of this is confusing, let me know! Unfortunately, I can't look at the autolayout via GitHub, but if that's also something you'd like me to look at, I'm happy to take the time.