I'll try to add the focus on a TextView inside a Popover, but I wont work at the moment. It should get the focus direct after load.
I use:
override func viewDidAppear(animated: Bool) {
self.textView.resignFirstResponder()
}
But nothing happens. Any ideas?
You're making a confusion between -becomeFirstResponder and -resignFirstResponder. Your code has to be:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
self.textView.becomeFirstResponder()
}
self.textView.becomeFirstResponder()
Related
I am developing an iOS application where I am streaming a live video from youtube. After exiting the full-screen mode the status bar overlays the navigation bar in all views (as seen in this picture)
I have searched for this problem and found a solution which is adding the following code in a function that is executed after exiting the full-screen mode:
#objc func videoExitFullScreen (_ sender: Any?){
navBar.frame.origin = CGPoint(x: 0, y: 20)
}
This code successfully solved the problem. However, I need to place this code in every controller of my application. When I tried to place it in the app delegate as the following it did not solve the problem:
#objc func videoExitFullScreen (_ sender: Any?){
UINavigationBar.appearance().frame.origin = CGPoint(x: 0, y: 20)
}
Do you have any suggestions where I can place the code in one place and it will solve the problem?
try like this
// create a new class of type UIViewController
class BaseViewController : UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.videoExitFullScreen()
}
func videoExitFullScreen (){
navBar.frame.origin = CGPoint(x: 0, y: 20)
}
}
// replace UIViewController to BaseViewController
class ViewController: BaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
}
Use Auto Layout and pin your view to Top Layout Guide, or use the new Safe Area Layout Guides. To enable it, in your storyboard's File inspector tick the following option.
I have a UITabBar containing 5 tabs. I disabled one of the tabs like this:
tabBar.items?[3].isEnabled = false
To enable it again, I am using the following code:
tabBar.items?[3].isEnabled = true
The problem is that it doesn't actually get enabled again. I also tried to place the above code inside viewWillAppear and viewDidAppear, but the tab stays disabled.
Here's the full code:
import UIKit
class MainTabViewController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
tabBar.items?[0].title = NSLocalizedString("tab1", comment: "-")
tabBar.items?[1].title = NSLocalizedString("tab2", comment: "-")
tabBar.items?[2].title = NSLocalizedString("tab3", comment: "-")
tabBar.items?[3].title = NSLocalizedString("tab4", comment: "-")
tabBar.items?[4].title = NSLocalizedString("tab5", comment: "-")
self.tabBar.items?[3].isEnabled = true
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
}
It should be the tabBar property of the UITabBarController.
self.tabBarController?.tabBar.items?[3].isEnabled = false
If you call it from inside the custom UITabBarController subclass:
self.tabBar.items?[3].isEnabled = false
Make sure viewWillAppear and viewDidAppear of the custom UITabBarController subclass are called only once, unlike the methods in every tab, since they are called every time the tab is selected.
The below code seems to work fine:
self.tabBar.items?[3].isEnabled = false
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
self.tabBar.items?[3].isEnabled = true
}
I need to add Tap Gesture on Navigation Bar or View.
I got the below solution which works perfectly fine.
But removeGestureRecognizer is not removing the gesture and it's breaking the functionality of other back buttons in other view controllers.
How to fix the issue?
var taskTodoOnBar : UITapGestureRecognizer!
override func viewWillAppear(animated: Bool)
{
navigationController?.view.addGestureRecognizer(taskTodoOnBar)
}
override func viewWillDisappear(animated: Bool)
{
navigationController?.view.removeGestureRecognizer(taskTodoOnBar)
}
Or
override func viewWillAppear(animated: Bool)
{
navigationController?.navigationBar.addGestureRecognizer(taskTodoOnBar)
}
override func viewWillDisappear(animated: Bool)
{
navigationController?.navigationBar.removeGestureRecognizer(taskTodoOnBar)
}
When I try to get gestureRecognizers count, It says nil. Then where is the gesture being added ?
override func viewWillDisappear(animated: Bool)
{
print(navigationController!.view.gestureRecognizers!.count)
print(navigationController!.navigationBar.gestureRecognizers!.count)
}
Try using this
Declared gesture as
let tapGesture : UITapGestureRecognizer = UITapGestureRecognizer()
Gesture Handler
#objc func tapHandler(handler: UITapGestureRecognizer){
print("gesture Added")
}
Added in Navigation bar as
override func viewDidLoad()
{
super.viewDidLoad()
tapGesture.numberOfTapsRequired = 1
tapGesture.addTarget(self, action: #selector(VC2.tapHandler(handler:)))
self.navigationController?.view.addGestureRecognizer(tapGesture)
}
Removed as
override func viewWillDisappear(_ animated: Bool) {
for gesture in (navigationController?.view.gestureRecognizers)! {
if gesture == tapGesture {
navigationController?.view.removeGestureRecognizer(tapGesture)
print("removed")
}
}
}
Updated Answer for - gesture count prints nil
console Output :
After help from iOS Geek, I figured out that, gestureRecognizers!.count was 2 in ViewdDidLoad but was nil inside viewWillDisappear.
Then I dug more and discovered that I had written the custom code for my back button.
So in such case, we Should removeGestureRecognizer before popToViewController
So this is for all whom I wish not to make mistake like me while using the custom back button.
func backBarBtnFnc(sender: UIBarButtonItem)
{
navigationController?.navigationBar.removeGestureRecognizer(taskTodoOnBar)
// CodTdo ...
self.navigationController!.popToViewController(VC2, animated: true)
}
In my code, when a view disappears, a specific action occurs. I am doing it through the viewDidDisappear() function.
I have a specific button that when is pressed it goes to another view. I was wondering in what I way I could tell ONLY the function caused by a specific button to skip the viewDidDisappear().
I perfectly know I can add a sort of 'if' statement in the viewDidDisappear() but I was wondering if there was a more efficient method.
viewDidDisappear() is a UIViewController's lifecycle callback method that's called by the environment - as far as I know there is no way to disable its calling. And I don't think there should be - as I mentioned, it is a part of UIViewController's lifecycle, not calling it would break the contract - see its documentation.
Therefore you have to (and you should) achieve what you want by using if statement.
Do something like this:
fileprivate var skipDisappearingAnimation = false
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
prepareInterfaceForDisappearing()
}
fileprivate func prepareInterfaceForDisappearing() {
guard !skipDisappearingAnimation else {
// reset each time
skipDisappearingAnimation = false
return
}
// do the stuff you normally need
}
#objc fileprivate func buttonPressed(_ sender: UIButton) {
skipDisappearingAnimation = true
// navigate forward
}
It cannot be done; you must handle the case manually with if, something like:
var shouldSkip: Bool = false
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
if !shouldSkip {
// your code goes here
}
shouldSkip = false // don't forget to set should skip to false again
}
#IBAction func buttonDidTap(_ sender: Any) {
shouldSkip = true // this will avoid run your code
// your code here
}
In the shortcut bar of iOS virtual keyboard there is an undo button that undoes the editing. Is there a way to associate an arbitrary button to that function?
From iOS 8, shaking the device should trigger the undo operation. Your view controller should be the first responders so it can response to the undo trigger. You can have that by becoming the first responder one the view is about to appear and then resign it when it is about to disappear
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
becomeFirstResponder()
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
resignFirstResponder()
}
override func canBecomeFirstResponder() -> Bool {
return true
}
override func viewDidLoad() {
super.viewDidLoad()
}
Here is the solution I implemented (the same can be done for the redo function).
import UIKit
class ViewController: UIViewController, UITextViewDelegate {
#IBAction func undoButtonPressed(sender: AnyObject) {
mainTextField.undoManager?.undo()
enableDisableUndoButton()
}
func enableDisableUndoButton() { // to disable or enable the button when needed
if mainTextField.undoManager?.canUndo == true {
undoButton.enabled = true
} else {
undoButton.enabled = false
}
}
func textViewDidChange(mainTextField: UITextView) { // monitors when user makes changes in the text field
enableDisableUndoRedoButtons()
}
}
To get undoManager to take notes of the text changes made via code on the field, I use this:
mainTextField.replaceRange((theRange), withText: newStr)