selectedViewcontroller not working for tabbarcontroller in tvOS 10 - ios

I have a rootviewcontroller which is extending UITabBarController. It has several children viewcontrollers.
All I want is to programmatically select the 2nd/3rd/.. viewcontroller from the first one. I've used
`.selectedViewController`, `.selectedIndex`, `.navigationController.tabBarController.tabBar.selectedItem = ...`
and all the variations on this theme. I notice the following when using
`tabBarController.selectedViewController = tabBarController.viewControllers?[1]`
The tabBarController displays the 2nd viewcontroller for a second but goes back to the 1st viewcontroller. I have a hunch this is the focus engine but I'm lost at this point.

Not completely sure if it's related but I had a tvOS app where I had several UIViewControllers in a UITabBarController and I stopped being able to select them in the tab bar and have the tab bar go away once I upgraded to tvOS 10.
Turns out the issue is that those screens did not have any focusable elements on them (buttons, etc.) so I had to make subclass objects for some of the views and make the canBecomeFocused property return "true".
see: How to make a UIView focusable using the focus engine on Apple TV
You have to implement a second thing to make them appear focused but if you don't actually want that you can skip it.

I was setting an UITabBarItem for each controller.

Related

Compiling and running my tvOS project with the new Xcode13+, the tab bar scrolls with the scrollView and I can't access the split view controller

When I compile and run my tvOS project with the new Xcode13+, the tab bar scrolls with the scrollView, and I can't access the split view controller moving the focus.
The issue doesn't happen with Xcode < 13. However, after updating to Monterey, I don't have a choice.
Pre-condition:
Create an app on tvOS with a tab bar controller;
In one of the tab, put a split view controller;
In the collapsed master view controller, put a table view.
Issue 1:
Observe that moving the focus towards the left to open the collapsed master view controller, doesn't work anymore. The master view controller won't be pulled out. The only way to pull it out is to tap the back button (ex menu button).
Issue 2:
Scrolling down on the tableView in the master view controller would also scroll away the tab bar at the top (this was possible only setting the tabBarObservedScrollView before, but now is deprecated and it happens automatically. Even using [self setContentScrollView:nil forEdge:NSDirectionalRectEdgeAll] doesn't help.
Did anyone get the same problem? Do you know why this happens and if it can be solved?
In the meantime, I reported the problem to Apple.
PS. another odd thing is that the Apple documentation for setContentScrollView:forEdge: is empty (as of today).
Update:
Observe how even setting the property to nil, it is still populated:
After deeper investigation, I found that the problem happens only when compiling with Xcode13+ and running on tvOS15+.
For some reason, the property above is automatically populated for ALL UITableViewController.
Replacing the UITableViewController with a UIViewController with a UITableView inside solves the Apple issue.
This is a bug with Apple SDK:
Observe how even setting the property tabBarObservedScrollView to nil, it is still populated:
This happens for ALL UITableViewController.
Replacing the UITableViewController with a UIViewController with a UITableView inside wor the Apple issue.
--
Regarding the swipe left, it's another Apple bug or decision to not allow the focus to move on the master view controller when on a split view controller.

Passing through Segues, Determining what view the user is on and NavigationController buttons not appearing

Sorry for the long and possibly confusing question. In this I have 2 main problems with my code, those being: 1- When I embed my viewControllers in a UINavigationController and add a bar button item, nothing appears, yet it appears when I add it to the pageViewController. Secondly, I am wondering if there is a way to do this differently and use one button on the pageView (which appears on all viewcontrollers in it) and just determine what the user was looking at when they pressed the button and are taken to another viewcontroller.
I am trying to build a page-based application, and I have set up the application with 7 view controllers (One for each day of the week). I then have an AddViewController, where users can add data to a certain day. I was wondering if there is a way to only use 1 addView linked to the NavBar on the PageViewController, as when I embed all other viewControllers and add a bar button, it does not show up.
With the pageViewController being embedded, this is what it looks like with a bar button on it.
This then leads to:
Which works well, however I am wanting to pass data to various arrays (one for each viewController), and I want to know which ViewController the user wishes to add to (based off what day they were on). Is there a way to determine this and then unwind to the viewController and append the right data to the right array or should I have one addView per dayViewController? If that is the case, I am coming across the issue whereby the bar button items do not appear on the viewControllers when they are embedded in a navigationController. It looks like this:
StoryBoard: (Example: MondayViewController)
The outcome is a missing barButton: (Keep in mind I changed the tint Colour to white so it would be visible)
I was wondering if anyone has the answer to either of my problems, and once again, thanks for taking the time to look at this array of questions in one problem.
Any suggestions are welcome !
Rowan,
You can do this:
Create an UINavigationViewController and then embed an UIPageViewController in it.
In the data source for the UIPageViewController implement these two methods:
- pageViewController:viewControllerBeforeViewController:
- pageViewController:viewControllerAfterViewController:
Here you will return the correct instance of your DayViewController for each position (or nil if you are on the first/last page). Your data model would also be set here.
Add your "Add" bar button to the navigation bar of the UIPageViewController and let it push your AddViewController. When pushing the AddViewController provide to it the info on which day is currently visible. You will probably need to keep track of this your self. Use the - pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted: method of the UIPageViewController delegate.

Using multiple copies of the same view controller in a storyboard

I have the following setup in my app:
My initial view controller is a UITabBarController.
the tabs:
1)UINavigationController->PostListVC
2)UINavigationController->CategoriesListVC
3)UINavigationController->PostListVC
4)UINavigationController->PostListVC
5)UINavigationController->MoreViewController
As you can see, 3 tabs contain the same viewController class, but should not contain the same view controller object - the view will display different information based on information he gets form the AppDelegate.
What I did is I created 5 UINavigationControllers, connected them to the uitabbarcontroller, then created a rootViewController segue for 3 of them to the same PostListVC View - that way I don't need to maintain 3 designs of the same view.
The problem that I get is that only the first PostListVC gets created properly ( the leftmost in the tab bar ) - the other tabs that point to a PostListVC just show a black screen.
I've tried to illustrate the way I wire-up the storyboard using a 3-tab example:
As you can see, both the upper-most and lower-most views are connected to PostListVC.
I do not know what the issue is. I assume I'm using storyboards somewhat wrongly.
Does anybody know how I can fix this?
Thanks!
EDIT:
I have created a simple, example project (Xcode 5) that illustartes this issue:
http://www.speedyshare.com/Srwfg/TabBarProblem.zip
EDIT 2:
A modified version of the example, showing the problem with the offered solution:
http://speedy.sh/JkdGC/TabBarProblem-2.zip
There is no way to create different tabBarItems with this method, and there's no way to place the barItems so that they're not in a row - even if you try to chagne the order of segues.
As you said you need three different instances of PostListVC then you should create three different viewcontrollers of type PostListVC and connect each tab to its own. The class is the same but each tab gets its own instance.
I have got your example program to work BUT I don't know if the solution will work for your full project. Hopefully, it will put you on the correct track.
The solution is to have ONE (1) Navigation Controller / embedded root view but TWO (2) segues from the Tab Bar Controller. Here's the picture:
It looks like there's a problem with multiple UINavigationControllers linking to the same UIViewController. But no problem with the same UINavigationController linking to the same UIViewController provided they are instantiated separately through the UITabBarController.

Set up UITabBarController with three other view controllers

I have a UITabBarController inside of a TabBarViewController. I want to use this to connect my three other view controllers to a tab bar.
What I have so far: I have my three view controller, each with one UIView inside of them, ready to be paired with the tab bar to give easy navigation between them. I have also made a new Objective-C class of type UITabBarController. Inside the .xib of that I deleted the UIView and replaced it with a UITabBarController (not sure if this is right).
I'm new to Objective-C and Xcode so I don't know a whole deal about it all, so I may be doing this all wrong. Please correct me and try not to be too vague, thank you!
There's a tutorial here with two tabs:
http://www.youtube.com/watch?v=NfEK9JsCyXM
You can watch it and work with it to make it do 3 tabs.

Segues from a subView

Just trying to teach myself storyboarding and have run into a question I was hoping people may have an answer to.
I wanted to create a reusable upper toolbar so that in case I ever had to change it, it would update all of my scenes. I created a sized ViewController in my storyboard. I then load it into a subview of each of my scenes using the menu's identifier. THat seems to work pretty well (although, feel free to tell me that's the wrong way to do it).
Here's where the problem starts. On that top toolbar, I have a UIButton which I connect to another sized ViewController in my storyboard as a popover. Basically, a drop down menu. If I just load up the top toolbar, works fine. If I connect just a regular button to that popover scene using a segue, that works too. If, however, I try to click the button and follow the segue while the toolbar is within a subView I crash with EXC_BAD_ACCESS. I presume I'm not allowed to spawn a popOver from a subView or follow a segue within a subview? The latter seems wrong since you effectively do that with any UI object.
How else should I handle this?
Thanks!
I'd recommend using a UINavigationController and setting the toolbar to include your UIButton (as a UIBarButtonItem). If you have any trouble "keeping track" of the toolbar or button you can subclass UINavigationController, add the UIButton (or entire toolbar) as a property of the subclass, and access it from any subsequent view through the self.navigationController property (might violate strict OO, but you could use a protocol).
As for the popover, I think you're OK on iPad but not on iPhone. There are custom projects on github to implement UIPopoverController, and indeed the Facebook app makes use of a custom popover for notifications in their app. iPhone raises an exception if you try to show a UIPopoverController.

Resources