How to add imageView down the TabBar in TabBarController - ios

I want to add a imageView below/down the TabBar in TabBarController is there any way to do that. I searched a lot got one answer about adding the TabBarController in other ViewController's container view and add that image down that container view. I also try to add image programmatically but it covers the TabBar.
So how can i do that any suggestion would be appreciated.
Thank You.

Create one custom class inherit it from UITabarController and use the following code
class CustomTabbarController: UITabBarController {
override func loadView() {
super.loadView()
let imageView = UIImageView(frame: CGRect(x: 0, y: self.view.frame.size.height - 10, width: self.view.frame.size.width, height: 10))
imageView.backgroundColor = UIColor.red // set image you wanted to show
self.view.addSubview(imageView)
}
override func viewDidLayoutSubviews() {
tabBar.frame.origin.y = self.view.frame.size.height - 60 // change it according to your requirement
}
}
Now set the custom class to the Tabbarcontroller inside storyboard

Related

UIButton inside UIView inside UIScrollView not firing tap action

I've been looking for this for hours and have no luck yet. I want to use two custom views inside a scrollview. The first view have a button as a subview that leads the user to the next page(scrolls down). But the button action it's never fired. If I use the button as a scrollview subview everything works fine, but that's not what I want.
The code for the scrollview view controller:
class ViewController: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let redView = View1()
redView.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.scrollView.frame.height)
self.scrollView.addSubview(redView.view!)
let blueView = UIView(frame: CGRect(x: 0, y: self.scrollView.frame.height, width: self.view.frame.width, height: self.scrollView.frame.height))
blueView.backgroundColor = .blue
self.scrollView.addSubview(blueView)
self.scrollView.contentSize = CGSize(width: self.view.frame.width, height: self.scrollView.frame.height * 2)
}
func go(to page: Int) {
let y = CGFloat(page) * self.scrollView.frame.size.height
self.scrollView.setContentOffset(CGPoint(x: 0, y: y), animated: true)
}
}
ScrollView Storyboard Configuration
The code of the View1 Class:
class View1: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func didTouchUpInsideMoreInfoButton(_ sender: Any) {
print("test")
}
}
Any ideas are welcome. Thanks in advance.
Turn out that I was using a view controller's view and for some reason, the selectors don't work this way. So, what I did was to create a UIView only and then everything works just fine.
Check if the buttons userInteraction is enabled.
Sometimes if your button is inside another view, a UIView for example, it doesn't allow you to tap it. To fix this, you might want to add the button ON TOP of that view but not inside it. Make sure it's above but not inside any view in on your storyboard.

Push ViewController subviews beneath NavigationBar when translucent is True, Programmatically

This question asked to be implemented in Swift 4, iOS 11
Is there any way to make every subview of ViewController's view to be pushed down when it is under UINavigationBar?
If navigation bar is NOT TRANSLUCENT the subview is under it. This is what I want.
Desired Result
But when navigation bar is TRANSLUCENT the subview is lying under it. I dont want it. I want the subview is pushed down just be like if navigation bar is not translucent.
Undesired Result
I create the view programmatically :
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.red
let navBar = (self.parent as? UINavigationController)?.navigationBar
navBar?.isTranslucent = true
}
func makeChildView() {
let myframe = CGRect(x: 0, y: 10, width: self.view.frame.width, height:
self.view.frame.height * 0.4)
let view = UIView(frame: myframe)
view.backgroundColor = UIColor.green
self.view.addSubview(view)
}
Using Autolayout
I am able to solve this problem using autolayout. But I just want to know how to achieve this result without autolayout if possible. Is there any other approach?
Swift 3.x
navBar?.isTranslucent = true
self.automaticallyAdjustsScrollViewInsets = false
Add this line & you are good to go.

Make NavigationBar's titleView larger than itself

I want to place an image in the middle of a navigation bar that is bigger then the bar itself. So far I tried to use a UIView with a UIImageView inside and it works quite well as you can see here:
However as soon as I push another controller and pop back my ImageView gets cropped to the size of the NavigationBar again.
Any ideas on how to prevent the cropping?
My code so far for iOS 11:
override func viewDidLoad() {
super.viewDidLoad()
let logo = UIImage(named: "Logo")
let titleView = UIView(frame: CGRect(x: 0, y: 0, width: 60, height: 60))
let imageView = UIImageView(image: logo)
imageView.frame = CGRect(x: 0, y: 0, width: titleView.frame.width, height: titleView.frame.height)
titleView.addSubview(imageView)
imageView.contentMode = .scaleAspectFit
imageView.image = logo
navigationItem.titleView = titleView
}
Edit: Currently there is a temporary solution which uses an observer to overwrite the clipsToBounds property of the view that causes the trouble: Link (shout out to #trungduc for that)
I found why you got this issue. It's because of a private view which has name _UINavigationBarContentView. It's a subview of UINavigationBar. navigationItem.titleView is contained in this view.
At first time, when you change navigationItem.titleView. _UINavigationBarContentView.clipsToBounds is false .But after you push another controller and pop back, _UINavigationBarContentView.clipsToBounds is true. That's why titleView is cropped.
So i have a temporary solution. Each time when viewController appears, find this view and change _UINavigationBarContentView.clipsToBounds to false and layout titleView.
override func viewDidAppear(_ animated: Bool) {
for view : UIView in (navigationController?.navigationBar.subviews)! {
view.clipsToBounds = false;
}
navigationItem.titleView?.layoutIfNeeded()
}
override func viewWillAppear(_ animated: Bool) {
for view : UIView in (navigationController?.navigationBar.subviews)! {
view.clipsToBounds = false;
}
navigationItem.titleView?.layoutIfNeeded()
}
I tried and it works. But i think you shouldn't do something whit it because it's private view. Maybe Apple don't want us do anything with it.
Hope somehow my suggestion can help you. Good luck ;)
SOLUTION
Adding observer for _UINavigationBarContentView.clipsToBounds, each time when it changes to false, set to true and update layout of titleView
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let logo = UIImage(named: "Logo")
let titleView = UIView(frame: CGRect(x: 0, y: 0, width: 60, height: 60))
let imageView = UIImageView(image: logo)
imageView.frame = CGRect(x: 0, y: 0, width: titleView.frame.width, height: titleView.frame.height)
titleView.addSubview(imageView)
imageView.contentMode = .scaleAspectFit
imageView.image = logo
navigationItem.titleView = titleView
navigationController?.navigationBar.subviews[2].addObserver(self, forKeyPath: "clipsToBounds", options: [.old, .new], context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if (navigationController?.navigationBar.subviews[2].isEqual(object))! {
DispatchQueue.main.async {
self.navigationController?.navigationBar.subviews[2].clipsToBounds = false
self.navigationItem.titleView?.layoutIfNeeded()
}
}
}
deinit {
navigationController?.navigationBar.subviews[2].removeObserver(self, forKeyPath: "clipsToBounds")
}
For more detail and easier, you can check my demo here https://github.com/trungducc/stackoverflow/tree/big-title-navigation-bar
You could try to put the code in the viewWillAppear method. This way you will add the image to the bar everytime the view appears. However you should then remove the inageview within the viewDidDissappear method. If you need it in several views you could subclass the UIViewController and use this one.
The UINavigationBar has UIBarMetrics if you want a custom height but it's not fully interactive.
There's a bunch of code suggested by apple to actually develop nice things like iMessage app.

How to display UIView over keyboard in iOS

I want to create a simple view over keyboard, when users tap "Attach" button in inputAccessoryView.
Something like this:
Is there an easy way to do it? Or i should create my custom keyboard?
You can add that new subview to your application window.
func attach(sender : UIButton)
{
// Calculate and replace the frame according to your keyboard frame
var customView = UIView(frame: CGRect(x: 0, y: self.view.frame.size.height-300, width: self.view.frame.size.width, height: 300))
customView.backgroundColor = UIColor.redColor()
customView.layer.zPosition = CGFloat(MAXFLOAT)
var windowCount = UIApplication.sharedApplication().windows.count
UIApplication.sharedApplication().windows[windowCount-1].addSubview(customView);
}
Swift 4 version:
let customView = UIView(frame: CGRect(x: 0, y: self.view.frame.size.height - 300, width: self.view.frame.size.width, height: 300))
customView.backgroundColor = UIColor.red
customView.layer.zPosition = CGFloat(Float.greatestFiniteMagnitude)
UIApplication.shared.windows.last?.addSubview(customView)
The trick is to add the customView as a top subview to the UIWindow that holds the keyboard - and it happens to be the last window in UIApplication.shared.windows.
Swift 4.0
let customView = UIView(frame: CGRect(x: 0, y: self.view.frame.size.height-300, width: self.view.frame.size.width, height: 300))
customView.backgroundColor = UIColor.red
customView.layer.zPosition = CGFloat(MAXFLOAT)
let windowCount = UIApplication.shared.windows.count
UIApplication.shared.windows[windowCount-1].addSubview(customView)
As Tamás Sengel said, Apple's guidelines does not support adding a view over the keyboard. The recommended way to add a view over keyboard in Swift 4 & 5 is:
1) Add view with your "Next" button in your storyboard as external view and connect in your class (see Explain Image), in my case:
IBOutlet private weak var toolBar: UIView!
2) For the textfield you want to add your custom view over keyboard, add it as accessory view in viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
phoneNumberTextField.inputAccessoryView = toolBar
}
3) Add action for "Next" button:
#IBAction func nextButtonPressed(_ sender: Any) {
descriptionTextView.becomeFirstResponder()
// or -> phoneNumberTextField.resignFirstResponder()
}
Explain Image:
Method 2: Result with image
In TableView Controller - add stricked view at bottom
Please follow this great link to handle safe area for screens like iPhone X if you want to use this method(2). Article: InputAccessoryView and iPhone X
override var inputAccessoryView: UIView? {
return toolBar
}
override var canBecomeFirstResponder: Bool {
return true
}
Do you have find some effective method to solve this problem? In iOS9,you put your customView on the top of the windows:
UIApplication.sharedApplication().windows[windowCount-1].addSubview(customView);
But if the keyboard dismisses, the top Windows will be removed, so your customView will be removed.
Looking forward for your help!
Thank you for your help!
You can definitely add the view to your application’s window, and you can also add another window entirely. You can set its frame and level. The level could be UIWindowLevelAlert.
While this can be possible with accessing the topmost window, I would avoid doing this, as it clearly interferes with Apple's guidelines.
What I would do is dismissing the keyboard and replacing its frame with a view with same dimensions.
The keyboard's frame can be accessed from keyboard notifications listed here, their userInfo contain a key that can be accessed with UIKeyboardFrameEndUserInfoKey.

How to access UIView from the same xib using swift

Let me explain my problem here, I am working on a project in which I am having a xib file with a UIView. What I have done is, I created another UIView inside the same xib and I need to show that in my xib view in a button action using swift.
Note : If I tend to do this via programatically it is working fine but the problem while I am doing with my xib. (testview) is a view that I have created inside the xib.
class tableClass: UIViewController {
#IBOutlet var testview : UIView
override func viewDidLoad() {
super.viewDidLoad()
println(testview) **///// Return nil /////**
testview=UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200)) as UIView
println(testview) **///// Return nil /////**
self.view.bringSubviewToFront(testview)
self.view.addSubview(testview)
}
}
Thanks in Advance. Please let me know, your answers and valuable ideas.
I solved the above stated problem by initializing my UIView in ViewDidLoad method. Here, is the lines I wrote on my didLoad method
class tableClass: UIViewController {
#IBOutlet var testview : UIView = nil
override func viewDidLoad() {
super.viewDidLoad()
testview.frame = CGRectMake(0, 0, 0, 0)
self.view.addSubview(testview)
}}
After doing that, I can able to change the UIView frame anywhere from the class, like below. Happy Coding..
testview.backgroundColor = UIColor.greenColor()
testview.frame = CGRectMake(50, 50, 50, 50)

Resources