I'm sorry for this newbie question but here it goes. I'm just starting with iOS and implementing AdMob in my app. The app is running fine with the Ads working but I have four View Controllers and for the sake of test I just implement all theses methods in all View Controllers.
- (GADRequest *)createRequest
- (void)adViewDidReceiveAd:(GADBannerView *)adView
- (void)adView:(GADBannerView *)view
But imagine if I had 100 VC...There's a way to do it only in one file and import like a .h file? Yes, my OOP knowledge is limited and If somebody can help me I would appreciate.
Thanks
There is a tutorial on implementing a singleton for ads, but you'd still need to implement the listener methods (if you want them) for each View Controller because you may need to react differently in different situations.
Personally, I think it's cleaner to just have those methods in each of your VC that have ads, and reconsider which VCs need ads in them. Your title screen and options screen aren't great candidates - a best practice is to only put ads in VCs where your users will spend most of their time.
Just read your question and since it hasn't been answered yet, I would like to share my solution.
Create a ViewController that would act as base view controller for the rest of VCs. Implement the functions and listeners for ads in that base view controller and extend (inherit) rest of the VCs from this baseVC. Do all the work in the baseVC functions and if you need to add something different in a specific VC, you can do that and then call super of that function.
Hope this helps.
Related
Goal:
I need to be able to tell when a user is interacting with an iPhone app.
After 5 minutes, I will auto logout the user, but I don't want to do that if the user is interacting with the app.
I have read about shouldReceiveTouch:, but that it will be called if a user touches something. I could put login in there to reset the 5 minute timer.
How do I make it so that if any view on any screen is touched, the 5 minute timer starts over?
Is it possible to do this without implementing shouldReceiveTouch: everywhere?
Any help is appreciated.
There are at least 3 approaches:
(1) The best one I think is suggested in this post. Basically you would override -sendEvent: on UIApplication. But someone mentions this might not work anymore since iOS 7 - YMMV.
(2) Another, less clean solution would be to use method swizzling. You could replace a method on UIView for your own implementation, e.g. -touchesEnded:withEvent: or -hitTest:withEvent:.
(3) If your app doesn't use any 3rd party view controller, you could create a custom base class of UIViewController and make all your view controllers (except login view controller and anything shown before) inherit from this base class. This view controller would have a gesture recognizer or perhaps override a method like -touchesEnded:withEvent: or -hitTest:withEvent:.
For all approaches you would probably use a singleton to keep track of the last touched moment. Perhaps the singleton would use a countdown timer. The singleton could have a multicast delegate or use NSNotificationCenter to inform other view controllers that the timer has run out.
P.S.: I should note that you should consider method swizzling carefully. If some other project or library swizzles the same method, you will never know for sure which implementation is used for the swizzled method.
I am currently using a GLKView connected to a GLKViewController in my iOS project to animate the background of my app which works fine. Now I introduced a UITableViewController for displaying some list. I also would like to animate the table view's background similar to the other view controllers. But therefore I need something like a GLKTableViewController, but this doesn't exist.
Somebody any ideas ?
Finally I did implement the most important UITableViewController functionalities myself. Basically it's very simple, just implement the following two protocols/interfaces:
UITableViewDelegate
UITableViewDataSource
... with their corresponding implementations in the *.m file.
Hope this helps also other people. Regards.
In general, I've heard its better to use composition than inheritance, but it's not always clear to me how to do that. I want to create some functionality that's common across all of my view controllers (I want to listen for an NSNotification, and call a method if it receives the notif).
My idea is to create a BaseViewController that each UIViewController extends from. I'd love to solve this any other way than inheritance for many reasons
Some view controllers extend UIViewController and some extend UITableViewController
If I write it in swift, objc view controllers can't subclass it
Normal reasons for comp over inheritance - easier to understand the behavior
My question is - how do I accomplish this without copy and pasting a ton of code into each viewcontroller? I could obviously insert a line into each view controllers viewDidLoad method, to add a listener, and into each view controllers delloc, but I'd really rather avoid this. Is there other techniques that could make this cleaner?
In Swift 2.0 you can use protocol with default method implementations. But in this case is inheritance the best approach for me.
According to me, it will be better to implement some functionality which is common across all ViewControllers by using Singleton Class.
Create a simple swift file having Singleton class in it and implement common functions in it which you want to access anywhere. Create a shared instance for that class and by using this shared instance, you can call any function in any ViewController of your application. So that you can reuse the code without copy-paste.
I am building a music player app -- in this app, the music player view controller will always sit on top of any other sub-viewcontroller (navigation view, table views, etc) I need actions taken in any potential subview to be sent back up to the player view controller (for example, user selects "play" on a profile page, and I send that event back up) My question is what is the best way to do this? I apologize in advance for being a bit nebulous, but I already know of three ways I can implement it. I just want to know what the "right" way is.
These are the three ways I've thought of:
1.Delegate pattern -- pass the Music Player Controller off to it's children controllers and set itself as the delegate for whenever that event is passed (messy because the first view controller is a navigation view controller, so I think I'd have to pass it down several levels meaning several delegates (correct me if I'm wrong))
2.Notification Center -- register the player view controller for a particular notification, encapsulate the data that's sent from the other viewcontrollers so that I can perform my actions.
3.Singleton-like access of the player view controller - basically allow access to the player view controller from any view controller.
Any help is appreciate to steer me in the right direction. I can do it either of these ways, but as this is a "learning" app, would love to do it right.
IMHO there is no "right way". Frankly I was thinking of all three of them when I read the subject line only.
As you are asing for opinions... I would not recommend the singleton pattern here. This is just because view controllers could stack and by their nature be instanciated multiple times. In terms of maintainable code (readability by others) I'd say no to that approach.
The delegate pattern is fine. But as you say you would have to pass a reference to this view controller from one view controller to the next. Yes, a bit messy.
Well, you could store a reference to the delegate in some singleton. That is not the same as designing a view controller as singleton.
I'd say that the notification center is most appropriate for this type of data flow. Sender and receiver of the message are totally detatched and don't need to 'know each other'. It is a perfect pattern for all kinds of multiple senders and/or mulitple receipient type of messages.
Well, as I said, this is just an opinion.
I would not recommend broadcast notifications (via NSNotificationCenter), they are hard to debug, other developers will have problems to understand, whats going on in your application (application flow), every developer must maintain a global list with all notification names (notificationSender and observer must use the same notification name and they are usually constant string variables), observer can not send back any data after receiving a notification, etc. Broadcasting is really helpful, if all controllers should be notified of the same event (for example Login/Logout events).
If possible, i think one should allways try to use a Delegate Pattern (with clearly defined protocol). Maybe something like:
id <SubViewControllerEvents>musicPlayerVC= [MyMusicAppManager delegate];
if ( [musicPlayerVC respondsToSelector:#selector(userDidSelectPlay)] ) {
[musicPlayerVC userDidSelectPlay];
}
I'm currently trying to build my own Custom ContainerViewController.
I'm quite familiar with the iOS ViewController containment API (introduced in iOS 5) and the new iOS7 ViewController Transition API.
While implementing my container, i tried to utilize the same patterns UINavigationController and UITabBarController are using.
My Container is working well so far and using animated and interactive transitions properly.
The Problem is, i packed a huge amount of the logic into my UIViewController container subclass. It is conforming to <UIViewControllerContextTransitioning> and uses iVars to store all the values returned by that protocol's methods.
The animation and interaction logic is already separated in another class and third-parties are also able to provide their own transition using a delegate similar to UINavigationControllerDelegate and UITabBarControllerDelegate.
What I'm trying to do now is out-sourcing the UIViewControllerContextTransitioning to a separate class to create the same modularity Apple does for it's containerVCs.
Apple provides a UIViewControllerOneToOneTransitionContext (private API) for the id<UIViewControllerContextTransitioning> object handed to the UIViewControllerAnimatedTransitioning and UIViewControllerInteractiveTransitioning methods. So they are NOT using their UIViewController subclass for that. (That's what i do at the moment)
My current structure is in so far tempting to keep for me as when the transition logic calls [updateInteractiveTransition:], [completeTransition:], etc. on the context, these calls are made directly on my containerController which can then respond by updating other elements in it's view. (Like UINavigationController does when you call [updateInteractiveTransition:] and it's updating the content of the NavigationBar (cross-fade)).
Out-Sourcing the contexttransitioning logic in another class would mean:
Provide the viewControllers and frames, etc. which are hold in the stack of my container FROM the container TO the context object because the context needs to provide them to the transition logic.
Call transition-callbacks FROM the context object ON the container because the context object is the one receiving them from the transition logic.
As Apple uses this class-relationship, there must be some advantage about it, i guess.
Currently, i don't know if i should keep my implementation, or try to make it as modular as Apple-provided containers.
Also see this SO - Question where i asked the same thing. (More like an answer-question, sorry for that :/ )
While we're on the topic : Is it possible to make my container work with UIPercentDrivenInteractiveTransition ? The documentation says it cuts the animation executed by the transitionAnimator in keyframes and automagically "replays" the animated transition step by step, so i doubt it can be used with custom containers.
Thanks for your help !
Apple uses a lot of small classes conforming to certain protocols to hand over pieces of work. Divide and conquer. Have a look at for instance the way UITableView operates or collection view. They did split things into smallest chunks possible, and provided each one with some generic objects. These objects only conform to certain Protocols.
Do not force people to subclass.
Create protocols that classes fulfilling certain roles have to conform to.
Where you want to create ready to use objects that will perform certain actions - return id type of object, not a class object. That's the only way to keep things simple and flexible enough.
Apple does that even with NSObject, which is both a class and protocol.
When creating your own protocols, remember to make them conform to NSObject * protocol.
Your question is rather long, and does not ask any specific questions, so I hope this answers some of your concerns. If not, feel free to post one to response to this.