How to prevent navbar hiding when keyboard appears ios? - swift

I have an app which has a webview on a storyboard, which loads a registration form in ASP, so when the keyboard or a picker appears, the navbar hides, but never comes back, so I'm not able to go back to the last page.
Here's my code:
import UIKit
class BannerViewController: UIViewController {
#IBOutlet var webView11: UIWebView!
override var preferredStatusBarStyle: UIStatusBarStyle {
return .default
}
override var prefersStatusBarHidden: Bool {
return false
}
override func viewWillAppear(_ animated: Bool) {
self.navigationItem.setHidesBackButton(false, animated: true)
self.setNeedsStatusBarAppearanceUpdate()
self.navigationController?.navigationBar.barTintColor = UIColor(red: 0, green: 0.38, blue: 0.667, alpha: 1)
self.navigationController?.navigationBar.tintColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1)
var titleTextAttributes = [String : AnyObject]();
titleTextAttributes[NSFontAttributeName] = UIFont.systemFont(ofSize: 17, weight: UIFontWeightSemibold)
titleTextAttributes[NSForegroundColorAttributeName] = UIColor(red: 1, green: 1, blue: 1, alpha: 1)
self.navigationController?.navigationBar.titleTextAttributes = titleTextAttributes
}
override func viewDidLoad() {
super.viewDidLoad();
self.navigationController?.navigationBar.barStyle = .default
self.setNeedsStatusBarAppearanceUpdate()
self.navigationController?.setNavigationBarHidden(false, animated: true)
self.webView11.delegate = self;
if let unwrappedwebView11 = URL(string: "http://www.stackoverflow") {
self.webView11.loadRequest(URLRequest(url: unwrappedwebView11))
}
}
}
extension BannerViewController: UIWebViewDelegate {
}

So, it looks like i need to refresh the view or something, as i added a back button out of the webView and when i click and go back to last view, and then i got in again to the webView the navBar doesn´t move anymore

Related

Is it possible to customize UINavigationBar by protocol?

I want to customize UINavigationBar for some view controllers. For some reasons, I cannot just simply extend UIViewController. So I was trying to do it by a protocol.
What I have tried:
protocol TransparentNavigationBarProtocol {
func makeNavigationBarTransparent()
}
extension TransparentNavigationBarProtocol where Self: UIViewController {
func makeNavigationBarTransparent() {
if let navController = navigationController {
navController.navigationBar.setBackgroundImage(UIImage(), for: .default)
navController.navigationBar.shadowImage = UIImage()
navController.navigationBar.tintColor = UIColor.white
navController.navigationBar.barStyle = .blackTranslucent
navController.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
navController.navigationBar.backgroundColor = .clear
}
}
}
I added some breakpoints which show the function had been called successfully but the navigationBar didn't change. So I was wondering is it possible to achieve this by protocols?
For Xcode11, you need set a image, not nil
Also, in your viewcontroller's viewWillAppear, you need call makeNavigationBarTransparent()
func makeNavigationBarTransparent() {
if let navController = navigationController {
navController.navigationBar.setBackgroundImage(UIImage(), for: .default)
navController.navigationBar.shadowImage = UIImage()
navController.navigationBar.tintColor = UIColor.init(red: 74/255, green: 74/255, blue: 74/255, alpha: 1)
navController.navigationBar.barStyle = .default
navController.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor(red: 74/255, green: 74/255, blue: 74/255, alpha: 1)]
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
makeNavigationBarTransparent()
}

AZTabBarController doesn't stick to bottom

I'm trying to implement AZTabBarController within my project but I am struggling to fix the bar to the bottom of the screen. My assumption is that the bar can be fixed to the bottom using some method or that I have some element that is pushing the bar some 50pts higher. Perhaps there is a margin of some sort that keeps the bar from staying at the bottom. Any suggestions will be much appreciated.
Here is my AZTabBar code. I've borrowed it from the example within the repo.
class CustomTabBarController: UITabBarController {
var tabController: AZTabBarController!
override func viewDidLoad() {
super.viewDidLoad()
var icons = [UIImage]()
icons.append(UIImage.init(named: "ic_home")!)
icons.append(UIImage.init(named: "ic_new")!)
icons.append(UIImage.init(named: "ic_settings")!)
//The icons that will be displayed for each tab once they are selected.
var selectedIcons = [UIImage]()
selectedIcons.append(UIImage.init(named: "ic_home")!)
selectedIcons.append(UIImage.init(named: "ic_new")!)
selectedIcons.append(UIImage.init(named: "ic_settings")!)
tabController = AZTabBarController.insert(into: self, withTabIcons: icons, andSelectedIcons: selectedIcons)
tabController.delegate = self
tabController.setViewController(QueryViewController.instance(), atIndex: 0)
tabController.setViewController(SettingsViewController.instance(), atIndex: 2)
//customize
let color = UIColor(red: 14.0/255, green: 122.0/255, blue: 254.0/255, alpha: 1.0)
tabController.selectedColor = color
tabController.highlightColor = color
tabController.highlightedBackgroundColor = #colorLiteral(red: 0.1803921569, green: 0.8, blue: 0.4431372549, alpha: 1)
tabController.defaultColor = .lightGray
//tabController.highlightButton(atIndex: 2)
tabController.buttonsBackgroundColor = UIColor(red: (247.0/255), green: (247.0/255), blue: (247.0/255), alpha: 1.0)//#colorLiteral(red: 0.2039215686, green: 0.2862745098, blue: 0.368627451, alpha: 1)
tabController.selectionIndicatorHeight = 0
tabController.selectionIndicatorColor = color
tabController.tabBarHeight = 60
tabController.setAction(atIndex: 0) {
//Your statments
print("Home!")
}
tabController.setAction(atIndex: 1) {
//Your statments
print("NEW Situation!")
}
tabController.setAction(atIndex: 2) {
//Your statments
print("Settings")
}
tabController.animateTabChange = false
tabController.onlyShowTextForSelectedButtons = false
tabController.setTitle("Home", atIndex: 0)
tabController.setTitle("New", atIndex: 1)
tabController.setTitle("Settings", atIndex: 2)
//tabController.font = UIFont(name: "AvenirNext-Regular", size: 12)
}
override var childForStatusBarStyle: UIViewController?{
return tabController
}
func getNavigationController(root: UIViewController)->UINavigationController{
let navigationController = UINavigationController(rootViewController: root)
navigationController.title = title
navigationController.navigationBar.isTranslucent = false
navigationController.navigationBar.barStyle = .black
navigationController.navigationBar.isTranslucent = false
navigationController.navigationBar.barTintColor = #colorLiteral(red: 0.7450980544, green: 0.1568627506, blue: 0.07450980693, alpha: 1)
return navigationController
}
}
Sub classing
class CustomTabBarController: UITabBarController {
is the reason you should use AZTabBarController directly , what you see as margin in bottom is the parent class's tabBar which is empty because you don't set any viewControllers for it

How to customise UISearchController?

I'm using a UISearchController in my application but I can't figure a way to customise it. I looked here in Stackoverflow but none of the confirmed answers worked for me. I tried looking in more places but nothing works.
This is my code:
import UIKit
class MainVC: UIViewController {
lazy var mSearchBarController: UISearchController = {
let mSearchBar = UISearchController(searchResultsController: nil)
mSearchBar.searchBar.barStyle = .default
mSearchBar.searchBar.placeholder = "enter city here"
mSearchBar.searchBar.tintColor = UIColor.white
return mSearchBar
}()
override func viewDidLayoutSubviews() {
setupSearchBar()
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor(red: 80/255, green: 135/255, blue: 179/255, alpha: 1.0)
setupNavBar()
self.navigationItem.searchController = mSearchBarController
}
private func setupNavBar(){
navigationItem.title = "Home"
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.hidesSearchBarWhenScrolling = true
}
private func setupSearchBar(){
let mSearchTextField = mSearchBarController.searchBar.value(forKey: "searchField") as? UITextField
mSearchTextField?.textColor = UIColor(red: 255/255, green: 245/255, blue: 139/255, alpha: 1.0)
let mAttributedPlaceholder = NSMutableAttributedString(string: "enter city here", attributes: [NSAttributedString.Key.foregroundColor : UIColor(red: 255/255, green: 245/255, blue: 139/255, alpha: 1.0)])
mSearchTextField?.attributedPlaceholder = mAttributedPlaceholder
for view in mSearchBarController.searchBar.subviews {
for subview in view.subviews {
if let textField = subview as? UITextField {
textField.backgroundColor = UIColor.red
textField.textColor = UIColor.white
}
}
}
}
}
I can't figure a way to change the textColor of the searchBar nor the backgroundColor of it.
This is what I get:
See I use this simple code to change the textColor and backgroundColor of seacrhBar:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var searchBar: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
for view in searchBar.subviews {
for subview in view.subviews {
if let textField = subview as? UITextField {
textField.backgroundColor = UIColor.red
textField.textColor = UIColor.white
}
}
}
}
for reference you can check:-
How can I change the UISearchBar search text color? (for textcolor)
http://jitu1990.blogspot.com/2017/06/textcolor-and-backgroundcolor.html (for backgorund color)

How to add Animation Button like this?

How can I create an animated and shadowed button like in this video
(Once you click the button, it shines and swings)
Here is my code:
(This code implement swing and shadow but needs to be organized and arranged so that it is capable of running the light and the swing with one click and the button doesn't move from its place unnecessarily)
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var aBtn: ButtonWithShadow!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func btnClick(_ sender: UIButton) {
if sender.isSelected {
sender.isSelected = false
sender.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.50).cgColor
sender.layer.shadowOffset = CGSize(width: 0, height: 3)
sender.layer.shadowOpacity = 1.0
sender.layer.shadowRadius = 10.0
sender.layer.masksToBounds = false
} else {
sender.isSelected = true
sender.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.0).cgColor
}
aBtn.layer.anchorPoint = CGPoint(x: 0.5, y: 0)
aBtn.layer.transform = CATransform3DMakeRotation(-.pi / 15, 0, 0, 1)
let needleAnim = CABasicAnimation(keyPath: "transform.rotation.z")
needleAnim.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
needleAnim.duration = 1.0 as? CFTimeInterval ?? CFTimeInterval()
needleAnim.repeatCount = 5
needleAnim.autoreverses = true
// Setting fillMode means that, once the animation finishes, the needle stays in its end position.
needleAnim.fillMode = kCAFillModeForwards
needleAnim.isRemovedOnCompletion = true
needleAnim.toValue = Double.pi / 15
aBtn.layer.add(needleAnim, forKey: nil)
}
}
and
import UIKit
class ButtonWithShadow: UIButton {
override func draw(_ rect: CGRect) {
//updateLayerProperties()
}
}
Thanks for your time
Your code works as written and provides a swinging button when clicked. Make sure you control-click dragged from the button to the button definition.
You'll need to add two images to your button, one for the off state and one for the on state.
and on
Here is the intermediate result of adding setting the images.
and the way to change the images is to add them to the assets catalog and then change them with :
if sender.isSelected {
sender.isSelected = false
sender.setImage(#imageLiteral(resourceName: "off"), for: .normal)
sender.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.50).cgColor
sender.layer.shadowOffset = CGSize(width: 0, height: 3)
sender.layer.shadowOpacity = 1.0
sender.layer.shadowRadius = 10.0
sender.layer.masksToBounds = false
} else {
sender.isSelected = true
sender.setImage(#imageLiteral(resourceName: "onbtn"), for: .normal)
sender.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.0).cgColor
}

How can I get a textview to trigger a scrollview to move up for the keyboard?

I'm creating a form that lives on a view within a scrollview. It contains two textFields and one textView. I've cobbled together some code from online resources(like this one) so that it scrolls up if a textField is ever too low on the view/obstructed by the keyboard. The problem is that it doesn't seem to work for textViews.
I've done my best to comprehend why textViews won't trigger the same behavior, but I could really use some help. Here's my VC code:
import UIKit
class AddAPlaceBasicInfoViewController: UIViewController, UITextFieldDelegate, UITextViewDelegate {
// Outlets
#IBOutlet weak var nameTextField: UITextField!
#IBOutlet weak var categoryTextField: UITextField!
#IBOutlet weak var descriptionTextView: UITextView!
#IBOutlet weak var nextButton: UIButton!
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(noti:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(noti:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
// Default to an disabled "Next" button.
nextButton.isEnabled = false
nextButton.backgroundColor = UIColor(red: 89/255, green: 89/255, blue: 89/255, alpha: 1/1)
// Check that fields are filled.
nameTextField.delegate = self
descriptionTextView.delegate = self
// Helper functions.
createToolbar()
descriptionTextViewSetup(descriptionTextView)
}
// Creates the done button above the category picker.
func createToolbar() {
// Creates an instance of UIToolbar() named "toolbar".
let toolbar = UIToolbar()
toolbar.sizeToFit()
// Set up button properties.
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(AddAPlaceBasicInfoViewController.dismissKeyboard))
// Set color to teal.
doneButton.tintColor = UIColor(red: 0/255, green: 134/255, blue: 111/255, alpha: 1)
// Set up button in the toolbar and make it interactive.
toolbar.setItems([doneButton], animated: false)
toolbar.isUserInteractionEnabled = true
// Add the toolbar as an accessory view to the category picker.
nameTextField.inputAccessoryView = toolbar
categoryTextField.inputAccessoryView = toolbar
descriptionTextView.inputAccessoryView = toolbar
// Set toolbar's background to white.
toolbar.backgroundColor = UIColor.white
}
// Function to dismiss the keyboard. Used when the user taps the "Done" button in the toolbar.
func dismissKeyboard() {
view.endEditing(true)
if nameTextField.text?.characters.count == 0 || categoryTextField.text?.characters.count == 0 || descriptionTextView.text == "What's this place like? (You'll be able to add a photo on the next screen)" {
nextButton.isEnabled = false
nextButton.backgroundColor = UIColor(red: 89/255, green: 89/255, blue: 89/255, alpha: 1/1)
} else {
nextButton.isEnabled = true
nextButton.backgroundColor = UIColor(red: 0/255, green: 134/255, blue: 111/255, alpha: 1/1)
}
}
// Function to create placeholder text.
func descriptionTextViewSetup(_ textView: UITextView) {
// Modifications
descriptionTextView.text = "What's this place like? (You'll be able to add a photo on the next screen)"
descriptionTextView.textColor = UIColor(red: 199/255, green: 199/255, blue: 205/255, alpha: 1/1)
descriptionTextView.textContainer.lineFragmentPadding = 0
//descriptionTextView.textColor = UIColor.lightGray
}
//---------------------------------
// MARK: - Notification Center
//---------------------------------
func keyboardWillHide(noti: Notification) {
let contentInsets = UIEdgeInsets.zero
scrollView.contentInset = contentInsets
scrollView.scrollIndicatorInsets = contentInsets
}
func keyboardWillShow(noti: Notification) {
guard let userInfo = noti.userInfo else { return }
guard var keyboardFrame: CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue else { return }
keyboardFrame = self.view.convert(keyboardFrame, from: nil)
var contentInset:UIEdgeInsets = scrollView.contentInset
contentInset.bottom = keyboardFrame.size.height
scrollView.contentInset = contentInset
}
}
If you are creating a Form for users where they can enter information then I would suggest using a static UITableView. Static UITableView can be used if your UIViewController is of type UITableViewController. Static TableView makes it very easy to place controls and since UITableView already has a UIScrollView it automatically scrolls when the UITextView is in focus.
Try it out: