Create Segue from Custom Cell UIButton to a ViewController - uiviewcontroller

I want to create a segue from (a) a UIButton (in a custom cell of a tableview) and (b) a custom cell in general to a UIViewController. The custom cell is specified in a .xib file. I read that I just should control drag from the UIButton / custom cell to the UIViewController. That doesn't work for me.
The .xib file of the custom cell isn't inside the storyboard - that's right?
I thought about that it should be inside the storyboard. If necessary, how can I do that?
How can I create a segue from the UIButton (in a custom cell) / custom cell to the UIViewController?
Thanks!
EDIT: I'm using a UITableViewController as Source, the destination is a UIViewController with a UITableView.

Ctrl-drag from the tableViewController (not from the prototype cell) to your target viewController and assign an identifier name to the segue.
Now override didSelectRowAtIndexPathto perform the segue with your identifier when tapping that cell:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
performSegueWithIdentifier("yourSegue", sender: nil)
}
Distinguish between the cells based on your indexPath and create as many segues as you need to your target viewControllers.
You can do similar for the button in your custom cell. Perform the segue on the button's action.

I used xcode6beta5 that should be the problem. Now I'm using xCode6 GM and the creation of the segues works absolutely fine like zisoft wrote! Thanks man!!

Related

How to Click Specific Text in a WKWebView to Perform an Action in Swift

I'm using a WKWebview on my story board. I need a way for clicking on specific text to perform an action.
Assume I have a webkit added:
#IBOutlet weak var webkit: WKWebView!
And then later on I have:
webkit.loadHTMLString("Click here or there for different actions", baseURL: nil)
How could I set this up so that clicking on the word "here" would perform code of my choosing, and clicking on "there" would perform different code of my choosing.
It needs to be set up in a webkit like this because I need to use html (the above is just an example).
I had thought about trying to do this through linking. For example:
webkit.loadHTMLString("Click <a href=''>here</a> or there for different actions", baseURL: nil)
And then run something like I found in this question's answer:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Void) {
if navigationAction.navigationType == WKNavigationType.linkActivated {
print("run code")
decisionHandler(WKNavigationActionPolicy.cancel)
return
}
decisionHandler(WKNavigationActionPolicy.allow)
}
However this seems messy as I don't actually need website links. And this only works for one specific action. Clicking on any link would allow me to run some kind of code, but I want specific code for specific words.
Any guidance would be greatly appreciated!

AutoLayout for a presented ViewController

I have implemented a custom viewController transition whereby I present a new ViewController as a pop-over. This resembles something like an alertViewController. I have written the transition handler and set my presenting viewController as the delegate and than preset this presented view controller like this:
#IBAction func pickOption(sender: UIButton) {
let storyBoard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyBoard.instantiateViewControllerWithIdentifier("OptionVC")
vc.modalPresentationStyle = .OverCurrentContext
vc.transitioningDelegate = self
self.presentViewController(vc, animated: true, completion: nil)
}
Here is where I am confused about proceeding with the layout. I wish to have this presented ViewController take up a small fraction of the frame of the presenting ViewController's View, preferably using Autolayout to set margin constraints. However, both the ViewController's in this are separate scenes in Interface Builder.
In the transition handler, the canonical thing to do seems to be adding the presented ViewController's view to a "context" view and handle animations there. Then call transitionContext.completeTransition(). Now that the presented ViewController's view is a subview of the presenting ViewController's view, I would like the autolayout constraints to be present but as I previously stated this isn't obvious how to do given both views are in separate scenes in IB.
Thanks in advance for any advice for guidance.

remembersLastFocusedIndexPath not working on UICollectionView

I have a collection view with a standard horizontal layout. Upon presenting a view controller and then dismissing it, the collection view reset focus back to the first cell, even though the last focused cell was not that one.
I've set
self.collectionView.remembersLastFocusedIndexPath = YES;
What's weird is that this only happens when I push a view controller on my navigation controller.
So if I do
[self.navigationController pushViewController:controller animated:YES];
and then dismiss, remembersLastFocusedIndexPath does not work properly.
However, if I:
[self presentViewController:controller animated:YES completion:nil];
Then it works as expected.
Any idea why it wouldn't work via a navigation controller?
What worked for me was ensuring that preferredFocusView on the viewController was the collection view:
override weak var preferredFocusedView: UIView? {
return collectionView
}
After this remembersLastFocusedIndexPath seems to work.
make sure that you don't reloadData() on viewWillAppear of your collectionView or TableView. Otherwise rememberedFocus will be reseted to default (for collection view in my case it was the centre visible cell)
By default, the system remembers the position. You should probably fix this issue by setting remembersLastFocusedIndexPath to false.
You could also implement the UICollectionViewDelegate method:
func indexPathForPreferredFocusedViewInCollectionView(collectionView: UICollectionView) -> NSIndexPath?
The documentation tells us:
The functionality of this delegate method is equivalent to overriding the UICollectionView class’s preferredFocusedView method in the UIFocusEnvironment protocol. If the collection view’s remembersLastFocusedIndexPath method is set to YES, this method defines the index path that gets focused when the collection view is focused for the first time.
But for your issue, setting remembersLastFocusedIndexPath to false should fix it.
You can also try to implement similar behaviour. Just remember last focused cell in
func collectionView(collectionView: UICollectionView, didUpdateFocusInContext context: UICollectionViewFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator)
and use this information in
func collectionView(collectionView: UICollectionView, canFocusItemAtIndexPath indexPath: NSIndexPath) -> Bool
For 2022, this is still a severe Apple bug.
Simply does not work:
navigationController?.pushViewController(details, animated: false)
Works perfectly:
present(details, animated: false)
There are no workarounds, currently:
It seems in the far past some workarounds would make it work. There are no workarounds presently. It is just "utterly broken".
Unfortunately, all you can do is file it under the usual heading "You must be joking, Apple."

When to access subview properties in UIViewController Lifecycle?

Context of Problem:
I am trying to learn how to use the storyboard in Xcode 6 by placing three UIViews in the storyboard's topmost viewcontroller. One of the UIView's is blue, one is red, and one is yellow. I am trying to see if I can alter the UIView's programmatically by changing the background color of one of the UIViews. By Command + clicking the UIViewController class and looking at the appropriate functions to override, I've determined "viewDidAppear" is the final function to be called by the UIViewController in its setup code.
Problem:
Here is my override of the function:
override func viewDidAppear(animated: Bool) {
self.bottomView!.backgroundColor = UIColor.blackColor()
super.viewDidAppear(animated)
}
However, when I run this code the the screen with the three UIViews appears for a split second, with NO black-colored UIView, and then proceeds to crash with a
"fatal error: unexpectedly found nil while unwrapping an Optional value"
Question:
What function do I have to override in order to be able to programmatically change the properties of the UIView? What is the best-practices method of doing so?
EDIT:
I am using Storyboard so my three UIView's are declared in the beginning of my UIViewController class as such:
#IBOutlet var topLeftView: UIView?
#IBOutlet var topRightView: UIView?
#IBOutlet var bottomView: UIView?
It seems that none of the views are actually initialized when viewDidLoad gets called, because the result of the following line of code
println("\(bottomView?)")
is "nil". How come this isn't getting initialized?
This is best done in viewDidLoad. viewDidAppear is called when the view is added into the view hierarchy, but it was not yet initiated. viewDidLoad is called when the view is allocated into memory. According to the docs for viewDidLoad:
You usually override this method to perform additional initialization on views that were loaded from nib files
You should override viewDidLoad and modify your UIView's in there.

Hiding UITabBar when showing UIViewController as modal

I've got a UIViewController that has a modal window which I'd like to present over the entire interface, including the UITabBar.
My application hierarchy is this:
UITabBarController (A) ->
UIViewController (B) ->
UINavigationController (C) ->
UIViewController (D) ->
UIViewController (my modal view)
When I call presentModalViewController on D, the modal view is presented but underneath the UITabBar, or should I say, the UITabBar is still shown.
I've tried setting the hidesBottomBarWhenPushed property to YES on the modal view controller, but to no avail.
Any ideas on why this isn't working for me?
The modal ViewController needs to be a direct child of the TabBarController in order to do what you want.
in ViewController "D", instead of :
[self presentModalViewController:...];
do:
[tabBarController presentModalViewController:...];
how you maintain a reference to the TabBarController is up to you.