Tap on ParentViewController closes the ChildViewController - ios

I have a ViewController which has add button which will open SideBarVC on right side of screen.
If I tap on my main ViewController screen again It should close my SideBarVC.
I tried
#IBAction func click_leistung(_ sender: UIButton) {
leistungList = self.storyboard?.instantiateViewController(withIdentifier: "leistungVC") as! leistungVC
leistungList.view.backgroundColor = .clear
leistungList.modalPresentationStyle = .overCurrentContext
self.present(leistungList, animated: true, completion: nil)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.myscrollView.endEditing(false)
leistungList.removeFromParentViewController()
leistungList = nil
}

First of all - you trying to remove fresh VC, but you should store pointer to old one to remove it. Create var to store pointer to this leistungList and then remove it from parent.
var storedController: UIViewController?
func show() {
// ...
storedController = presentedController
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// Das keyboard ist weg
self.myscrollView.endEditing(false)
storedController.removeFromParentViewController()
storedController = nil
}
PS: read this article to understand how to manage child controllers https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html

Related

Restrict navigation bar from hide on button tap

I wants to hide navigation bar on tap. So i used this method of navigation bar.
self.navigationController?.hidesBarsOnTap = true
Have 2 button on screen and when i tap on that button for perform some action it is also hiding navigation bar. I think button click consider as tap.
Can you please let me know, is it correct behaviour ? Also please let me know if there is any way to restrict this. I don't want to hide navigation bar on button tap, rest of parts of screen will be fine.
You can create your custom button and handle touches on to enable/disable hiding bars e.g.:
class BarHideOnTapButton : UIButton {
weak var navigationController: UINavigationController?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
self.navigationController?.hidesBarsOnTap = false
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
self.navigationController?.hidesBarsOnTap = true
}
}
class ViewController: UIViewController {
#IBOutlet var button: BarHideOnTapButton?
override func viewDidLoad() {
super.viewDidLoad()
self.button?.navigationController = self.navigationController
self.navigationController?.hidesBarsOnTap = true
}
...
}

Button changing after image moves over it?

I am making a "slide to confirm" button, the set up is a custom UIButton + a regular UIImageView, the image is passed to the button and the button listen to touches and move the image accordingly.
Everything is working great except for one detail after the button is released everything should go back to their initial state, yet the button stay changed as if its alpha was halved
i commented the alpha because the button was going to hide but i disabled that once i run into this problem, the problem happens regardless of setting the alpha or not.
This is the code for the custom button
class SlideButton: UIButton {
var arrowImage: UIImageView?
var initialLocation: CGPoint?
var initialArrowPosition: CGPoint?
func setArrow(arrow:UIImageView){
arrowImage = arrow
initialArrowPosition = arrow.frame.origin
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
let touch = touches.first!
let location = touch.location(in: self.superview)
initialLocation = location
UIView.animate(withDuration: 0.2) {
//self.alpha = 0.0
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
UIView.animate(withDuration: 0.3) {
self.arrowImage!.frame.origin = self.initialArrowPosition!
//self.alpha = 1.0
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first!
let currentLocation = touch.location(in: self.superview)
arrowImage!.frame.origin.x = initialArrowPosition!.x - initialLocation!.x + (currentLocation.x)
}
}
You are remembering to call super for one of your touches methods:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
But for the other touches methods you've forgotten to do that, so you've broken the core functionality of the button.
you might have to also add an override to touchesCancelled because you might not always hit the touchesEnded endpoint.

Dismiss modal if anywhere but UITableViewCell is touched

I have a modal with a UITableView in it. I want to dismiss the modal if anywhere on the screen is touched except for the UITableViewCells inside the table view. However, you can't create an outlet for a UITableView cell to reference it in code. Currently I have this code:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch: UITouch? = touches.first
if touch?.view != WHAT TO PUT HERE? {
dismiss(animated: true, completion: nil)
}
}
I'm not sure how to reference the UITableViewCells. How should I do this?
I found a solution that works. I had to resize the tableView to fit the size of its content using this method:
override func viewDidAppear(_ animated: Bool) {
//Resize the tableView height to the height of its content.
tableView.frame.size.height = soundTableView.contentSize.height
//Set the origin of tableView to the bottom of the screen minus a 30px margin
//(this was my tableView's original position before resizing)
tableView.frame.origin.y = self.view.frame.size.height - soundTableView.frame.size.height - 30
}
Then I have this method which dismisses the modal if anywhere but the tableView is touched:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch: UITouch? = touches.first
if touch?.view != tableView {
dismiss(animated: true, completion: nil)
}
}

Can a subclass of UIButton trigger segues?

Is it possible for a subclass of a UIButton to trigger a segue in storyboard?
The segue stop working as soon as I change the custom class of a button in storyboard.
I have UIPageViewController embedded in a ViewController inside a NavigationController. One of the ViewControllers in the PageController have a subclassed Button that should perform a segue in the NavigationController.
The Button subclass is as follows:
Every thing else is wired up in storyboard only
class MiniButton:UIButton{
var originalBackgroundColor:UIColor?
var originalTextColor:UIColor?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
originalBackgroundColor = self.backgroundColor
originalTextColor = self.titleColor(for: .normal)
self.backgroundColor = MiniColor.miniYellow
self.setTitleColor(MiniColor.white, for: .normal)
}
func backToOriginalColors(){
self.backgroundColor = originalBackgroundColor
self.setTitleColor(originalTextColor, for: .normal)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
backToOriginalColors()
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
backToOriginalColors()
}
}
Calling super on your subclass' methods is 'super' important =(
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event) // <--------
originalBackgroundColor = self.backgroundColor
originalTextColor = self.titleColor(for: .normal)
self.backgroundColor = MiniColor.miniYellow
self.setTitleColor(MiniColor.white, for: .normal)
}

Detect UIImageView Touch in Swift

How would you detect and run an action when a UIImageView is touched?
This is the code that I have so far:
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
var touch: UITouch = UITouch()
if touch.view == profileImage {
println("image touched")
}
}
You can detect touches on a UIImageView by adding a UITapGestureRecognizer to it.
It's important to note that by default, a UIImageView has its isUserInteractionEnabled property set to false, so you must set it explicitly in storyboard or programmatically.
override func viewDidLoad() {
super.viewDidLoad()
imageView.isUserInteractionEnabled = true
imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(imageTapped)))
}
#objc private func imageTapped(_ recognizer: UITapGestureRecognizer) {
print("image tapped")
}
You can put an UITapGestureRecognizer inside your UIImageView using Interface Builder or in code (as you want), I prefer the first. Then you can put an #IBAction and handle the tap inside your UIImageView, Don't forget to set the UserInteractionEnabled to true in Interface Builder or in code.
#IBAction func imageTapped(sender: AnyObject) {
println("Image Tapped.")
}
I hope this help you.
Swift 3
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch:UITouch = touches.first!
if touch.view == profileImage {
println("image touched")
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch:UITouch = touches.first!
if touch.view == profileImage {
println("image released")
}
}

Resources