I've tried to create a class in Swift, which autohides my UIStatusBar and my navigationController after 1 Second.
My problem is, that the StatusBar is not going to disappear. This is what I got:
override func viewDidLoad() {
super.viewDidLoad()
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "prefersStatusBarHidden", userInfo: nil, repeats: false)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
}
override func preferredStatusBarUpdateAnimation() -> UIStatusBarAnimation {
return UIStatusBarAnimation.Fade
}
override func prefersStatusBarHidden() -> Bool {
if (barcounter == 0){
hide()
barcounter = 1
return true
}
else {
show()
barcounter = 0
return false
}
}
#IBAction func picturePressed(sender: AnyObject) {
prefersStatusBarHidden()
}
func hide(){
UIView.animateWithDuration(1, delay: 1, options: UIViewAnimationOptions.CurveEaseOut, animations: {
self.navigationController?.navigationBar.alpha = 0.0
}, completion: nil)
}
func show(){
UIView.animateWithDuration(1, delay: 1, options: UIViewAnimationOptions.CurveEaseOut, animations: {
self.navigationController?.navigationBar.alpha = 1.0
}, completion: nil)
}
You need to override this method in whichever view controller u want to hide uistatusbar.
override func prefersStatusBarHidden() -> Bool {
return true;
}
if its not work then try this:-
In Info.plist set View controller-based status bar appearance to NO
And call UIApplication.sharedApplication().statusBarHidden = true
hope this helps you.
Alright.. I solved it like that:
I created a new class HeaderAnimationHelper in which I created the useable methods. Like that I can call it from everywhere.
So here you can see the Helper class:
import UIKit
class HeaderAnimationHelper {
static let sharedInstance = HeaderAnimationHelper()
var navi: UINavigationController!
func hideController(var barcounter: Int, navigationController: UINavigationController) -> Int {
navi = navigationController
if (barcounter == 0){
barcounter = 1
UIApplication.sharedApplication().setStatusBarHidden(true, withAnimation: UIStatusBarAnimation.Fade)
hide()
}
else {
show()
barcounter = 0
UIApplication.sharedApplication().setStatusBarHidden(false, withAnimation: UIStatusBarAnimation.Fade)
}
return barcounter
}
func hide(){
UIView.animateWithDuration(0.5, delay: 0, options: UIViewAnimationOptions.CurveEaseOut, animations: {
self.navi.navigationBar.alpha = 0.0
}, completion: nil)
}
func show(){
UIView.animateWithDuration(0.5, delay: 0, options: UIViewAnimationOptions.CurveEaseOut, animations: {
self.navi.navigationBar.alpha = 1.0
}, completion: nil)
}
}
and the next class is the main class in which you can put all you code and stuff...
I created it like that:
import UIKit
class ContactMeViewController: UIViewController {
var barcounter = 0
override func viewDidLoad() {
super.viewDidLoad()
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "animate", userInfo: nil, repeats: false)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
}
override func preferredStatusBarUpdateAnimation() -> UIStatusBarAnimation {
return UIStatusBarAnimation.Fade
}
#IBAction func picturePressed(sender: AnyObject) {
animate()
}
func animate(){
barcounter = HeaderAnimationHelper.sharedInstance.hideController(barcounter, navigationController: self.navigationController!)
}
}
edit 10/07/15:
I've forgotten to mention, that it's important to add the dependency to the Info.plist
In Info.plist set View controller-based status bar appearance to NO
Watch out this method UIApplication.sharedApplication().setStatusBarHidden(false, withAnimation: UIStatusBarAnimation.Fade)
is depricated
Related
I have searched as many posts as I found and still I cannot solve the problem. Please keep in mind that I have tried all the solutions provided that I have found and still when the keyboard appears the table does not scroll up, nor does it adjust its content view. The table v.c. is a child of a v.c., it is being pushed by the nav con (modal also does not work), below all of this sits a tab bar controller. Below is the code which I consider to be relevant.
Code inside the v.c.:
override func viewDidLoad() {
super.viewDidLoad()
safeGuide = self.view.safeAreaLayoutGuide
view.backgroundColor = UIColor.customColoursForAllElements(colourName: "background blue")
programMainMenu = self.tabBarController as? ProgramMainMenu
setTopViews()
let msgsArea = ChatMsgsAreaTVC(typeForCurrentInstance: .singleChat(otherMemberName: self.otherMemberName), userUID: self.userUID, searchResultMsg: msgSelectedInSearch != nil ? msgSelectedInSearch : nil, searchTxt: self.searchTxt)
msgsArea.valuesForSingleChat = chatDetails
displayChild(controller: msgsArea)
}
fileprivate func displayChild(controller: UIViewController) {
self.addChild(controller)
self.view.addSubview(controller.view)
controller.view.translatesAutoresizingMaskIntoConstraints = false
let childConstraints = [
controller.view.topAnchor.constraint(equalTo: detailsContainer.bottomAnchor, constant: 10),
controller.view.bottomAnchor.constraint(equalTo: safeGuide.bottomAnchor, constant: -55),
controller.view.leadingAnchor.constraint(equalTo: backBtn.leadingAnchor),
controller.view.trailingAnchor.constraint(equalTo: optionBtn.trailingAnchor)
]
NSLayoutConstraint.activate(childConstraints)
controller.didMove(toParent: self)
}
the code below is from the child table view controller:
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidHide), name: UIResponder.keyboardDidHideNotification, object: nil)
configureMsgsTable()
observeAudioRecAccess()
setupAudioRecorder()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.resignFirstResponder()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
DispatchQueue.main.async {self.becomeFirstResponder()}
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
NotificationCenter.default.removeObserver(self)
}
override var canBecomeFirstResponder: Bool {return true}
override var canResignFirstResponder: Bool {return true}
#objc func keyboardWillShow(notification: Notification) {
// note: changing the content size of the table does not work at all.
}
#objc fileprivate func keyboardDidHide() {
if !bypassForSetup {bypassForSetup = true}
else {
if msgTxtArea.isFirstResponder {msgTxtArea.resignFirstResponder()}
if addFileToMsgBtn.isSelected {addFileToMsgBtn.isSelected = false; addFileToMsgBtn.resignFirstResponder(); alterFileToMsgBtn(selected: false)}
}
}
fileprivate func configureMsgsTable() {
tableView.contentInsetAdjustmentBehavior = .always
tableView.backgroundColor = .clear
tableView.keyboardDismissMode = .interactive
tableView.separatorStyle = .none
tableView.showsVerticalScrollIndicator = false
tableView.estimatedRowHeight = 100
tableView.sectionFooterHeight = 0.0
tableView.scrollsToTop = false
tableView.setBottomInset(to: -15)
}
I also have a custom input accessory view that I have not included in this code.
I'm trying to make a button click in PopupViewController fill a textfield in DagbogsindlaegViewController with a string "svimmelhed, ".
I'm not getting any errors when running the code, but the text is not there when i run the app simulation and press "ButtonPressSvimmelhed" in the class PopupViewController.
Is there a kind stranger who can help me and tell me what i am doing wrong?
Code below:
import UIKit
import EventKit
class DagbogsindlaegViewController: UIViewController{
#IBAction func BackToSVC(_ sender: Any){
self.performSegue(withIdentifier: "BackToSVCSegue", sender: self)
}
#IBAction func ToCalenderButtonPress(_ sender: Any) {
self.performSegue(withIdentifier: "ToCalenderSegue", sender: self)
}
override func viewDidLoad() {
super.viewDidLoad()
TitleTextField.delegate = self
DescriptionTextField.delegate = self
// Do any additional setup after loading the view.
}
#IBOutlet weak var TitleTextField: UITextField!
#IBOutlet weak var DescriptionTextField: UITextField!
func addEventToCalendar(title: String, description: String?, startDate: Date, endDate: Date, completion: ((_ success: Bool, _ error: NSError?) -> Void)? = nil) {
let eventStore = EKEventStore()
eventStore.requestAccess(to: .event, completion: { (granted, error) in
if (granted) && (error == nil) {
let event = EKEvent(eventStore: eventStore)
event.title = title
event.startDate = startDate
event.endDate = endDate
event.notes = description
event.calendar = eventStore.defaultCalendarForNewEvents
do {
try eventStore.save(event, span: .thisEvent)
} catch let e as NSError {
completion?(false, e)
return
}
completion?(true, nil)
} else {
completion?(false, error as NSError?)
}
})
}
#IBAction func ButtonPressGemDagbog(_ sender: Any) {
addEventToCalendar(title: "\(String(describing: TitleTextField.text!))", description: "\(String(describing: DescriptionTextField.text!))", startDate: NSDate() as Date, endDate: NSDate() as Date)
}
#IBAction func ButtonPressPopupMenu(_ sender: Any) {
let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PopupViewControllerID") as! PopupViewController
self.addChild(popOverVC)
popOverVC.view.frame = self.view.frame
self.view.addSubview(popOverVC.view)
popOverVC.didMove(toParent: self)
}
}
extension DagbogsindlaegViewController : UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
extension DagbogsindlaegViewController : TextFraPopupDelegate {
func Symptomer(Svimmelhed: String) {
TitleTextField.text = Svimmelhed
}
}
And the other view controller:
import UIKit
protocol TextFraPopupDelegate{
func Symptomer(Svimmelhed: String)
}
class PopupViewController: UIViewController {
var symptomDelegate: TextFraPopupDelegate?
override func viewDidLoad() {
super.viewDidLoad()
self.showAnimate()
self.view.backgroundColor = UIColor.black.withAlphaComponent(0.8)
// Do any additional setup after loading the view.
}
#IBAction func ButtonPressBackToDagbogsindlaeg(_ sender: Any) {
self.removeAnimate()
//self.view.removeFromSuperview()
}
func showAnimate()
{
self.view.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
self.view.alpha = 0.0;
UIView.animate(withDuration: 0.25, animations: {
self.view.alpha = 1.0
self.view.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
});
}
func removeAnimate()
{
UIView.animate(withDuration: 0.25, animations: {
self.view.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
self.view.alpha = 0.0;
}, completion:{(finished : Bool) in
if (finished)
{
self.view.removeFromSuperview()
}
});
}
#IBAction func ButtonPressSvimmelhed(_ sender: UIButton) {
if sender.isSelected {
sender.isSelected = false
} else {
sender.isSelected = true
}
symptomDelegate?.Symptomer(Svimmelhed: "Svimmelhed, ")
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}
}
As mentioned in the comments the delegate is not set.
However in Swift there is a more convenient way to pass the string back to the presenting view controller, a callback closure. You get rid of the protocol and of the duty to set the delegate
Delete
protocol TextFraPopupDelegate{
func Symptomer(Svimmelhed: String)
}
In PopupViewController replace
var symptomDelegate: TextFraPopupDelegate?
with
var callback : ((String) -> Void)?
and
#IBAction func ButtonPressSvimmelhed(_ sender: UIButton) {
if sender.isSelected {
sender.isSelected = false
} else {
sender.isSelected = true
}
symptomDelegate?.Symptomer(Svimmelhed: "Svimmelhed, ")
}
with
#IBAction func ButtonPressSvimmelhed(_ sender: UIButton) {
sender.isSelected.toggle()
callback?("Svimmelhed, ")
}
In DagbogsindlaegViewController in ButtonPressPopupMenu add the closure
#IBAction func ButtonPressPopupMenu(_ sender: Any) {
let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PopupViewControllerID") as! PopupViewController
self.addChild(popOverVC)
popOverVC.view.frame = self.view.frame
popOverVC.callback = { string in
self.TitleTextField.text = string
}
self.view.addSubview(popOverVC.view)
popOverVC.didMove(toParent: self)
}
Finally delete
extension DagbogsindlaegViewController : TextFraPopupDelegate {
func Symptomer(Svimmelhed: String) {
TitleTextField.text = Svimmelhed
}
}
Notes:
The syntax (_ success: Bool, _ error: NSError?) -> Void)? is outdated. Since Swift 3 the parameter labels are gone, this is sufficient: (Bool, NSError?) -> Void)?
Don't use NS... classes in Swift if there are native counterparts for example Date
Please conform to the naming convention to name variables and functions / methods with a starting lowercase letter.
The syntax "\(String(describing: TitleTextField.text!))" is double redundant. You create a string from a string from a string. Replace it with TitleTextField.text!
I want to have a View with a textField an a send button above my keyboard, when the keyboard is shown. But this doesn't work.
I already implemented this in my code:
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_ :)), name: UIResponder.keyboardWillHideNotification, object: nil)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tabBarController?.tabBar.isHidden = true
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
tabBarController?.tabBar.isHidden = false
}
// MARK: - Keyboard stuff
#objc func keyboardWillShow(_ notification: NSNotification) {
let keyboardFrame = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as AnyObject).cgRectValue
print("hier ist \(keyboardFrame!)")
UIView.animate(withDuration: 0.1) {
self.bottomConstraint.constant = keyboardFrame!.height
self.view.layoutIfNeeded()
}
}
#objc func keyboardWillHide(_ notification: NSNotification) {
UIView.animate(withDuration: 0.1) {
self.bottomConstraint.constant = 0
self.view.layoutIfNeeded()
}
}
Check out textField inputAccessoryView. There's a tutorial here that explains what you're trying to do.
I use isHideStatusBar(true) and override two essential props for hide and show StatusBar in viewController
var statusBarShouldBeHidden = false
override var prefersStatusBarHidden: Bool {
return statusBarShouldBeHidden
}
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
return .slide
}
func isHideStatusBar(_ bool: Bool, _ delay : CFTimeInterval = 0){
statusBarShouldBeHidden = bool
UIView.animate(withDuration: 0.4, delay: delay, options: [], animations: {
self.setNeedsStatusBarAppearanceUpdate()
}) { (finished) in
}
}
how to put some line of this code in to UIViewController extension ?
Can be with a subclass
class MainViewController: UIViewController {
var statusBarShouldBeHidden = false
override var prefersStatusBarHidden: Bool {
return statusBarShouldBeHidden
}
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
return .slide
}
func isHideStatusBar(_ bool: Bool, _ delay : CFTimeInterval = 0){
statusBarShouldBeHidden = bool
UIView.animate(withDuration: 0.4, delay: delay, options: [], animations: {
self.setNeedsStatusBarAppearanceUpdate()
}) { (finished) in
}
}
}
class ViewController: MainViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
isHideStatusBar(true)
}
}
Extension ability is limited to contain stored properties & overrided methods
I am just trying to switch to a second view controller. I have my HomeViewController with this extension:
extension HomeViewController: UIViewControllerTransitioningDelegate {
func animationController(forPresented presented: UIViewController,
presenting: UIViewController,
source: UIViewController)
-> UIViewControllerAnimatedTransitioning? {
return transition
}
public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return nil
}
}
and transition defined in the class
let transition = PopAnimator()
I have a button that when it is tapped should switch view controllers and use custom transition (PopAnimator):
#objc func handleTap() {
let viewController = ViewController()
viewController.transitioningDelegate = self
self.present(viewController, animated: false, completion: nil)
}
PopAnimator class (really just a fadeIn for now):
class PopAnimator: NSObject, UIViewControllerAnimatedTransitioning {
let duration = 1.0
var presenting = true
var originFrame = CGRect.zero
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return duration
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let containerView = transitionContext.containerView
let toView = transitionContext.view(forKey: .to)!
containerView.addSubview(toView)
toView.alpha = 0.0
UIView.animate(withDuration: duration,
animations: {
toView.alpha = 1.0
},
completion: { _ in
transitionContext.completeTransition(true)
}
)
}
}
When I click the button, it switches viewControllers but doesn't use my custom transition. If I put a breakpoint in my animationController(forPresented:presenting:source:) function or my PopAnimator class it is not reached.
self.present(viewController, animated: false, completion: nil)
try setting animated: true if you want animated transition