I've been trying to implement Admob on swift and everything is good, but i run out of problem because I'm using custom table view cell and "Table view controller" as the main swift file, so when i am dragging the BannerView into the storyboard which is the table view controller, the ad actually appear in the first cell of the table view ! instead i need to load it at the button of the tableview controller not inside the cells ?
#IBOutlet weak var bannerView: GADBannerView!
override func viewDidLoad() {
super.viewDidLoad()
self.bannerView.adUnitID = "ca-app-pub-3940256099942544/2934735716"
self.bannerView.rootViewController = self
var request: GADRequest = GADRequest()
request.testDevices = [GAD_SIMULATOR_ID]
self.bannerView.loadRequest(request)
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
One solution could be to create a new instance of bannerView instead of having it as an outlet and then add it as a subview to the tableView's superview.
I had the same issue , i got it figured out by a slightly different method,
But it works like a charm.
So for all those Who are new to Swift and face this problem,
If Your using a story board, copy all your views( ex labels, UIImage's ) from the prototype cell
Go ahead and delete your View Controller. ( fear not , it will work eventually , trust me )
Drag a blank ViewController and in the class , mention your class associated with earlier tableView.
drag also tableview on it and selecting the tableview, put constraints form storyboard up & down-> 0 & left & right -> -20 .
drag a tableview cell, and selecting that cell, in class mention the cell class you were using for the earlier Tableview cell,
(tip-> You jus mite want to click on the module bellow the class and press enter, i got a stupid bug { unknown class in interface builder error , when i did it } )
now you can just select the cell and paste your earlier views in it and create a new connection with the cell class #IB outlets.
In the same Viewcontroller you can drag an empty UIView and make it a GADBannerView ( follow the Googles guide for admob iOS) Thats all in the IB
Now go to your tableview class , the class extension just make it to UIViewController , and confirm to protocols UITableViewDataSource & UITableViewDelegate.
ex: class Foo: UIViewController, UITableViewDataSource, UITableViewDelegate {
make a IB connection of your newly added UITableview in your main tableview (now viewController) class
#IBOutlet weak var Footableview: UITableView!
Now jus add these two lines in the viewDidLoad
Footableview.datasource = self
Footableview.delegate = self
Now just remove override form all tableview functions such as sections or RowForIndex functions, and wherever there is 'self.tableView' replace with 'self.Footableview'.
ScreenShot
Regards
Related
An UITableViewController pretty much takes up the entire view. I need a way to limit its height, width and add some shadows etc. For a clear explanation, I won't show the UITableViewController's contents.
Without the use of a storyboard, I subviewed the UITableViewController:
// In another UIViewController
let otherController = OtherController() // A subclass of UITableViewController
let otherControllerView = otherController.view
someView.addSubView(otherControllerView)
[...] // bunch of constraints
Notes:
In AppDelegate, if I set the rootController as OtherController(), everything works as it should. If I change it back to SomeView(), I see my modified tableView. If I should click it, it disappears.
This was the only thing that came close to my issue but sadly, I could not understand the answers provided as nothing made any sense to me.
I need to understand, why it disappears when touched etc.
view.bringSubviewToFront(...) proved futile. I'm gessing that a tableView should be rendered in its own controller and not in another view?
So just to answer this question, indeed you got two options. One is the best way, as suggested by Rakesha. Just use UITableView. Add it as a subview. Done.
And in the future, if you really want any controller to be added onto any UIView, remember you need to add that controller as a child. For example, in your case:
The controller of the view that will hold your UITableViewController will add such UITableViewController as a child.
self.addChild(yourUITableViewController)
self.whatEverViewContainer.addSubview(yourUITableViewController.view)
// Take note of the view of your tableViewController above^.
// Then setup the constraints of your yourUITableViewController.view below.
I hope this helps!
You must add the instance of UITableViewController's subclass as child view controller of the other view controller. You need to ensure few points in order to make it work. The points are as listed below:
Create the instance of your TableViewController
Add it as a child view controller of the other view controller
Add its view as a subview of the desired view (you may do these steps in viewDidLaod since they need to be done only once)
Keeping in mind the view cycle of a view controller. You must keep a weak reference of the child view controller aka TableViewController to adjust its view frame after the parent view controller has laid its subviews.
Code here:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let vc = TableViewController()
addChildViewController(vc)
view.addSubview(vc.view)
vc.didMove(toParentViewController: self)
childVC = vc
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
childVC?.view.frame = view.frame
}
I have a UIViewController and I dropped a UITableView and UIActivityIndicatorView in the same hierarchy and it's working fine.
But then I have a UITableViewController, with a UITableView of course, and I try to drop a UIActivityIndicatorView at the same hierarchy as the Table View but with no luck. I know that there's a problem with UITableViewController and UIViewController with Table View but how to solve?
These two screenshots will help to understand the problem.
The way I want it to be:
The way it turns out:
The problem is that with the UIViewController it has a self.view as the root view where you can add any sub-items as you did , put you can't do this at least in IB with UITableViewController as the root view is the table itself
First way
add it in code and control is position as the tableView scrolls so change it's frame in scrollViewDidScroll so it's stay at center of screen during the loading
Second way
add it to the main window of the app and remove it when loading finishes
Ok, guys I found one more solution.
Define a variable inside UITableViewController
weak var spinner: UIActivityIndicatorView!
then in viewDidLoad method make this (hope the code is self explanatory)
let activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray)
tableView.backgroundView = activityIndicatorView
tableView.separatorStyle = .none
self.spinner = activityIndicatorView
and then call spinner.startAnimating() when you need to show it, and
self.spinner.stopAnimating()
self.tableView.separatorStyle = .singleLine
to remove it when you don't need it.
When you drag and drop any view (no matter if it is UILabel or UIActivityIndicatorView or UIView),
if it is above the cell you put there, it will be treated as the TableViewHeader automatically.
if it is below the cell you put there, it will be treated as the TableViewFooter automatically.
That is the reason why they are at the same level of view hierarchy of cells.
If you really want to use the indicatorView at same level as your tableView in your tableViewController, even if you programmatically create it and add it to your tableviewcontroller's self.view, it WILL NOT work, because tableViewController's self.view is its content view, which is scrollable anyways, which is kinda a bummer. We only have full control in UIViewController.
I try to do something like this #IBoutlet var buttons : [UIButton]
but I can't drag button to this outlet
Any idea, how can I achieve that?
It's possible to do that.
Here is how:
Create an array of IBOutlets
Add multiple UIElements (Views) in your Storyboard ViewController interface
Select ViewController (In storyboard) and open connection inspector
There is option 'Outlet Collections' in connection inspector (You will see an array of outlets there)
Connect if with your interface elements
-
class ViewController2: UIViewController {
#IBOutlet var collection:[UIView]!
override func viewDidLoad() {
super.viewDidLoad()
}
}
To add a button to an existing array outlet, drag the other way 'round: from the circle in the margin of the view controller to the button. (No need to hold the control key while doing this drag.)
My question is technically a duplicate of this SO: How do I set custom navigation bar(title + titleView) for all navigation controllers and view controller?
The base class answer in the link above is my current solution as I will explain below. One problem with this solution though is that it makes my company logo image titleView disappear and reappear for a second with every segue, I am looking to keep the logo visible through all navigation transitions.
I am using a company logo in the center of my UINavigationBar. Currently, for any child UIView of my UINavigationViewController, I add a UINavigationItem outlet in the Xcode 7 Storyboard by CTRL Dragging to my Swift ChildViewController and always use the same ID:
#IBOutlet weak var uiNavItemTitle: UINavigationItem!
I then delete that above Xcode generated line because I have the same line in MyBaseViewController that ChildViewController inherits from. Now I can set the logo one time in MyBaseViewController and every ChildViewController inherits from MyBaseViewController, this code is in MyBaseViewController:
#IBOutlet weak var uiNavItemTitle: UINavigationItem!
override func viewDidLoad() {
super.viewDidLoad()
// MARK: - UINavigationController Defaults
uiNavItemTitle.titleView = CoreUtility.LogoForUINavBarGet()
self.navigationController?.navigationBar.topItem?.title = "";
self.navigationController?.navigationBar.tintColor = UIColor.whiteColor()
}
What is becoming an issue with this solution is that for every ChildViewController in my UINavigationViewController stack of segues, I have to add a UINavigationItem outlet and make sure I inherit MyBaseViewController. Some of my navigation segue views deeper in the navigation chain should not really inherit from this MyBaseViewController though.
Another issue with my solution is that the company logo disappears and reappears a second later for each segue to a new UIViewController
I can create another level to the hierarchy of inheritance is one possible solution.
But my UINavigationItem.titleView is always the same company logo for every child UIViewController segued to.
Do I have to add a UINavigationItem to every UIViewController?
Or is there an "Application" level way such as using, in my AppDeletgate.application():
//MARK: - UINavigationBar.appearance
UINavigationBar.appearance().tintColor = UIColor.whiteColor()
UINavigationBar.somethingForTitleView
Where somethingForTitleView becomes code to set a Application wide Navigation Bar titleView to my logo View.
I'm trying to add UIToolbar to my keyboard with inputAccessoryView, but once the user tap the UITextField I get an Blank white screen or load White view if i put it in viewDidLoad(). I have tried few stackoverflow QA and non of them seems to be working for me. I'm also doing this with removeFromSuperview() method.
Initialization:
#IBOutlet var MessegeView: UIToolbar!
#IBOutlet var MessegeTextField: UITextField!
Assign UIToolbar to UITextField: This code result in blank white view when it get loaded.
override func viewDidLoad() {
super.viewDidLoad()
MessegeTextField.inputAccessoryView = MessegeView
MessegeView.removeFromSuperview()
}
WITHOUT removeFromSuperView(): I get the following error and that make sense kind of.
ERROR:
should have parent view controller:<APPNAME.ChatViewController:XXXXXXXX> but requested parent is:<UIInputWindowController: XXXXXXXXXX>
A few Stackoverflow QA I follow (but no result):
Error when adding input view to textfield iOS 8
Leaving inputAccessoryView visible after keyboard is dismissed iOS8?
How views are setup:
If you setup your UI in a Storyboard then you don't own the objects and shouldn't alter the hierarchy. That's why Xcode auto-generated properties from storyboards are #IBOutlet weak var by default, you don't own them and shouldn't manage the memory.
To fix your problem you should either use var MessegeView = UIToolbar() or you should initialize the toolbar from a separate .xib.