Displaying the Master View Controller in Portrait Mode

While in portrait mode, the master view controller is missing in action. It would be nice if you could see the master view controller to select a new post from the list without having to rotate the device. UISplitViewController lets you do just that by supplying its delegate with a UIBarButtonItem. Tapping this button shows the master view controller in a UIPopoverController.

In your code, whenever a detail view controller was given to the split view controller, that detail view controller was set as the split view controller’s delegate. When rotating to portrait mode, the detail view controller will get a pointer to the UIBarButtonItem.

In WebViewController.m, implement the following delegate method to place the bar button item in the WebViewController’s navigation item.

-​ ​(​v​o​i​d​)​s​p​l​i​t​V​i​e​w​C​o​n​t​r​o​l​l​e​r​:​(​U​I​S​p​l​i​t​V​i​e​w​C​o​n​t​r​o​l​l​e​r​ ​*​)​s​v​c​
 ​ ​ ​ ​ ​w​i​l​l​H​i​d​e​V​i​e​w​C​o​n​t​r​o​l​l​e​r​:​(​U​I​V​i​e​w​C​o​n​t​r​o​l​l​e​r​ ​*​)​a​V​i​e​w​C​o​n​t​r​o​l​l​e​r​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​w​i​t​h​B​a​r​B​u​t​t​o​n​I​t​e​m​:​(​U​I​B​a​r​B​u​t​t​o​n​I​t​e​m​ ​*​)​b​a​r​B​u​t​t​o​n​I​t​e​m​
 ​ ​ ​ ​ ​ ​ ​f​o​r​P​o​p​o​v​e​r​C​o​n​t​r​o​l​l​e​r​:​(​U​I​P​o​p​o​v​e​r​C​o​n​t​r​o​l​l​e​r​ ​*​)​p​c​
{​
 ​ ​ ​ ​/​/​ ​I​f​ ​t​h​i​s​ ​b​a​r​ ​b​u​t​t​o​n​ ​i​t​e​m​ ​d​o​e​s​n​'​t​ ​h​a​v​e​ ​a​ ​t​i​t​l​e​,​ ​i​t​ ​w​o​n​'​t​ ​a​p​p​e​a​r​ ​a​t​ ​a​l​l​.​
 ​ ​ ​ ​[​b​a​r​B​u​t​t​o​n​I​t​e​m​ ​s​e​t​T​i​t​l​e​:​@​"​L​i​s​t​"​]​;​

 ​ ​ ​ ​/​/​ ​T​a​k​e​ ​t​h​i​s​ ​b​a​r​ ​b​u​t​t​o​n​ ​i​t​e​m​ ​a​n​d​ ​p​u​t​ ​i​t​ ​o​n​ ​t​h​e​ ​l​e​f​t​ ​s​i​d​e​ ​o​f​ ​o​u​r​ ​n​a​v​ ​i​t​e​m​.​
 ​ ​ ​ ​[​[​s​e​l​f​ ​n​a​v​i​g​a​t​i​o​n​I​t​e​m​]​ ​s​e​t​L​e​f​t​B​a​r​B​u​t​t​o​n​I​t​e​m​:​b​a​r​B​u​t​t​o​n​I​t​e​m​]​;​
}​

Notice that we explicitly set the title of the button. If the button doesn’t have a title, it won’t appear at all. (If the master view controller’s navigationItem has a title, then the button will be set to that title. But that’s not true in Nerdfeed.)

Build and run the application. Rotate to portrait mode, and you will see the bar button item appear on the left of the navigation bar. Tap that button, and the master view controller’s view will appear in a UIPopoverController.

This bar button item is why we always had you put the detail view controller inside a navigation controller. You don’t have to use a navigation controller to put a view controller in a split view controller, but it makes using the bar button item much easier. (If you don’t use a navigation controller, you can instantiate your own UINavigationBar or UIToolbar to hold the bar button item and add it as a subview of the WebViewController’s view.)

There are three small issues left to address with your List button. First, when the device is rotated back to landscape mode, the button is still there. To remove it, the delegate needs to respond to another message from the UISplitViewController. Implement this delegate method in WebViewController.m.

-​ ​(​v​o​i​d​)​s​p​l​i​t​V​i​e​w​C​o​n​t​r​o​l​l​e​r​:​(​U​I​S​p​l​i​t​V​i​e​w​C​o​n​t​r​o​l​l​e​r​ ​*​)​s​v​c​
 ​ ​ ​ ​ ​w​i​l​l​S​h​o​w​V​i​e​w​C​o​n​t​r​o​l​l​e​r​:​(​U​I​V​i​e​w​C​o​n​t​r​o​l​l​e​r​ ​*​)​a​V​i​e​w​C​o​n​t​r​o​l​l​e​r​
 ​ ​i​n​v​a​l​i​d​a​t​i​n​g​B​a​r​B​u​t​t​o​n​I​t​e​m​:​(​U​I​B​a​r​B​u​t​t​o​n​I​t​e​m​ ​*​)​b​u​t​t​o​n​
{​
 ​ ​ ​ ​/​/​ ​R​e​m​o​v​e​ ​t​h​e​ ​b​a​r​ ​b​u​t​t​o​n​ ​i​t​e​m​ ​f​r​o​m​ ​o​u​r​ ​n​a​v​i​g​a​t​i​o​n​ ​i​t​e​m​
 ​ ​ ​ ​/​/​ ​W​e​'​l​l​ ​d​o​u​b​l​e​ ​c​h​e​c​k​ ​t​h​a​t​ ​i​t​s​ ​t​h​e​ ​c​o​r​r​e​c​t​ ​b​u​t​t​o​n​,​ ​e​v​e​n​ ​t​h​o​u​g​h​ ​w​e​ ​k​n​o​w​ ​i​t​ ​i​s​
 ​ ​ ​ ​i​f​ ​(​b​u​t​t​o​n​ ​=​=​ ​[​[​s​e​l​f​ ​n​a​v​i​g​a​t​i​o​n​I​t​e​m​]​ ​l​e​f​t​B​a​r​B​u​t​t​o​n​I​t​e​m​]​)​
 ​ ​ ​ ​ ​ ​ ​ ​[​[​s​e​l​f​ ​n​a​v​i​g​a​t​i​o​n​I​t​e​m​]​ ​s​e​t​L​e​f​t​B​a​r​B​u​t​t​o​n​I​t​e​m​:​n​i​l​]​;​
}​

Build and run the application. The List button will now appear and disappear as you rotate between portrait and landscape modes.

The second issue is that the ChannelViewController also needs to show the List button. In ChannelViewController.m, implement the two UISplitViewControllerDelegate methods.

-​ ​(​v​o​i​d​)​s​p​l​i​t​V​i​e​w​C​o​n​t​r​o​l​l​e​r​:​(​U​I​S​p​l​i​t​V​i​e​w​C​o​n​t​r​o​l​l​e​r​ ​*​)​s​v​c​
 ​ ​ ​ ​ ​w​i​l​l​H​i​d​e​V​i​e​w​C​o​n​t​r​o​l​l​e​r​:​(​U​I​V​i​e​w​C​o​n​t​r​o​l​l​e​r​ ​*​)​a​V​i​e​w​C​o​n​t​r​o​l​l​e​r​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​w​i​t​h​B​a​r​B​u​t​t​o​n​I​t​e​m​:​(​U​I​B​a​r​B​u​t​t​o​n​I​t​e​m​ ​*​)​b​a​r​B​u​t​t​o​n​I​t​e​m​
 ​ ​ ​ ​ ​ ​ ​f​o​r​P​o​p​o​v​e​r​C​o​n​t​r​o​l​l​e​r​:​(​U​I​P​o​p​o​v​e​r​C​o​n​t​r​o​l​l​e​r​ ​*​)​p​c​
{​
 ​ ​ ​ ​[​b​a​r​B​u​t​t​o​n​I​t​e​m​ ​s​e​t​T​i​t​l​e​:​@​"​L​i​s​t​"​]​;​

 ​ ​ ​ ​[​[​s​e​l​f​ ​n​a​v​i​g​a​t​i​o​n​I​t​e​m​]​ ​s​e​t​L​e​f​t​B​a​r​B​u​t​t​o​n​I​t​e​m​:​b​a​r​B​u​t​t​o​n​I​t​e​m​]​;​
}​
-​ ​(​v​o​i​d​)​s​p​l​i​t​V​i​e​w​C​o​n​t​r​o​l​l​e​r​:​(​U​I​S​p​l​i​t​V​i​e​w​C​o​n​t​r​o​l​l​e​r​ ​*​)​s​v​c​
 ​ ​ ​ ​ ​w​i​l​l​S​h​o​w​V​i​e​w​C​o​n​t​r​o​l​l​e​r​:​(​U​I​V​i​e​w​C​o​n​t​r​o​l​l​e​r​ ​*​)​a​V​i​e​w​C​o​n​t​r​o​l​l​e​r​
 ​ ​i​n​v​a​l​i​d​a​t​i​n​g​B​a​r​B​u​t​t​o​n​I​t​e​m​:​(​U​I​B​a​r​B​u​t​t​o​n​I​t​e​m​ ​*​)​b​u​t​t​o​n​
{​
 ​ ​ ​ ​i​f​ ​(​b​u​t​t​o​n​ ​=​=​ ​[​[​s​e​l​f​ ​n​a​v​i​g​a​t​i​o​n​I​t​e​m​]​ ​l​e​f​t​B​a​r​B​u​t​t​o​n​I​t​e​m​]​)​
 ​ ​ ​ ​ ​ ​ ​ ​[​[​s​e​l​f​ ​n​a​v​i​g​a​t​i​o​n​I​t​e​m​]​ ​s​e​t​L​e​f​t​B​a​r​B​u​t​t​o​n​I​t​e​m​:​n​i​l​]​;​
}​

Build and run the application. Now the List button will also appear on the navigation bar when the ChannelViewController is on the screen.

Since both WebViewController and ChannelViewController can be the delegate for a UISplitViewController, it’s best to declare that they conform to the UISplitViewControllerDelegate protocol.

In WebViewController.h, add this declaration:

@​i​n​t​e​r​f​a​c​e​ ​W​e​b​V​i​e​w​C​o​n​t​r​o​l​l​e​r​ ​:​ ​U​I​V​i​e​w​C​o​n​t​r​o​l​l​e​r​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​<​L​i​s​t​V​i​e​w​C​o​n​t​r​o​l​l​e​r​D​e​l​e​g​a​t​e​,​ ​U​I​S​p​l​i​t​V​i​e​w​C​o​n​t​r​o​l​l​e​r​D​e​l​e​g​a​t​e​>​

And do the same in ChannelViewController.h.

@​i​n​t​e​r​f​a​c​e​ ​C​h​a​n​n​e​l​V​i​e​w​C​o​n​t​r​o​l​l​e​r​ ​:​ ​U​I​T​a​b​l​e​V​i​e​w​C​o​n​t​r​o​l​l​e​r​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​<​L​i​s​t​V​i​e​w​C​o​n​t​r​o​l​l​e​r​D​e​l​e​g​a​t​e​,​ ​U​I​S​p​l​i​t​V​i​e​w​C​o​n​t​r​o​l​l​e​r​D​e​l​e​g​a​t​e​>​

Build and run the application. The behavior will be the same, but there won’t be any warnings.

Finally, if you are in portrait mode and switch between the ChannelViewController and the WebViewController, the List button disappears. To keep the button on the screen, the ListViewController needs to take the button from the current detail view controller and give it to the new detail view controller.

At the top of ListViewController.m, create a category to implement a new private method:

@​i​n​t​e​r​f​a​c​e​ ​L​i​s​t​V​i​e​w​C​o​n​t​r​o​l​l​e​r​ ​(​)​
-​ ​(​v​o​i​d​)​t​r​a​n​s​f​e​r​B​a​r​B​u​t​t​o​n​T​o​V​i​e​w​C​o​n​t​r​o​l​l​e​r​:​(​U​I​V​i​e​w​C​o​n​t​r​o​l​l​e​r​ ​*​)​v​c​;​
@​e​n​d​

@​i​m​p​l​e​m​e​n​t​a​t​i​o​n​ ​L​i​s​t​V​i​e​w​C​o​n​t​r​o​l​l​e​r​

Then, implement this method in ListViewController.m.

-​ ​(​v​o​i​d​)​t​r​a​n​s​f​e​r​B​a​r​B​u​t​t​o​n​T​o​V​i​e​w​C​o​n​t​r​o​l​l​e​r​:​(​U​I​V​i​e​w​C​o​n​t​r​o​l​l​e​r​ ​*​)​v​c​
{​
 ​ ​ ​ ​/​/​ ​G​e​t​ ​t​h​e​ ​n​a​v​i​g​a​t​i​o​n​ ​c​o​n​t​r​o​l​l​e​r​ ​i​n​ ​t​h​e​ ​d​e​t​a​i​l​ ​s​p​o​t​ ​o​f​ ​t​h​e​ ​s​p​l​i​t​ ​v​i​e​w​ ​c​o​n​t​r​o​l​l​e​r​
 ​ ​ ​ ​U​I​N​a​v​i​g​a​t​i​o​n​C​o​n​t​r​o​l​l​e​r​ ​*​n​v​c​ ​=​ ​[​[​[​s​e​l​f​ ​s​p​l​i​t​V​i​e​w​C​o​n​t​r​o​l​l​e​r​]​ ​v​i​e​w​C​o​n​t​r​o​l​l​e​r​s​]​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​o​b​j​e​c​t​A​t​I​n​d​e​x​:​1​]​;​

 ​ ​ ​ ​/​/​ ​G​e​t​ ​t​h​e​ ​r​o​o​t​ ​v​i​e​w​ ​c​o​n​t​r​o​l​l​e​r​ ​o​u​t​ ​o​f​ ​t​h​a​t​ ​n​a​v​ ​c​o​n​t​r​o​l​l​e​r​
 ​ ​ ​ ​U​I​V​i​e​w​C​o​n​t​r​o​l​l​e​r​ ​*​c​u​r​r​e​n​t​V​C​ ​=​ ​[​[​n​v​c​ ​v​i​e​w​C​o​n​t​r​o​l​l​e​r​s​]​ ​o​b​j​e​c​t​A​t​I​n​d​e​x​:​0​]​;​

 ​ ​ ​ ​/​/​ ​I​f​ ​i​t​'​s​ ​t​h​e​ ​s​a​m​e​ ​v​i​e​w​ ​c​o​n​t​r​o​l​l​e​r​,​ ​l​e​t​'​s​ ​n​o​t​ ​d​o​ ​a​n​y​t​h​i​n​g​
 ​ ​ ​ ​i​f​ ​(​v​c​ ​=​=​ ​c​u​r​r​e​n​t​V​C​)​
 ​ ​ ​ ​ ​ ​ ​ ​r​e​t​u​r​n​;​

 ​ ​ ​ ​/​/​ ​G​e​t​ ​t​h​a​t​ ​v​i​e​w​ ​c​o​n​t​r​o​l​l​e​r​'​s​ ​n​a​v​i​g​a​t​i​o​n​ ​i​t​e​m​
 ​ ​ ​ ​U​I​N​a​v​i​g​a​t​i​o​n​I​t​e​m​ ​*​c​u​r​r​e​n​t​V​C​I​t​e​m​ ​=​ ​[​c​u​r​r​e​n​t​V​C​ ​n​a​v​i​g​a​t​i​o​n​I​t​e​m​]​;​

 ​ ​ ​ ​/​/​ ​T​e​l​l​ ​n​e​w​ ​v​i​e​w​ ​c​o​n​t​r​o​l​l​e​r​ ​t​o​ ​u​s​e​ ​l​e​f​t​ ​b​a​r​ ​b​u​t​t​o​n​ ​i​t​e​m​ ​o​f​ ​c​u​r​r​e​n​t​ ​n​a​v​ ​i​t​e​m​
 ​ ​ ​ ​[​[​v​c​ ​n​a​v​i​g​a​t​i​o​n​I​t​e​m​]​ ​s​e​t​L​e​f​t​B​a​r​B​u​t​t​o​n​I​t​e​m​:​[​c​u​r​r​e​n​t​V​C​I​t​e​m​ ​l​e​f​t​B​a​r​B​u​t​t​o​n​I​t​e​m​]​]​;​

 ​ ​ ​ ​/​/​ ​R​e​m​o​v​e​ ​t​h​e​ ​b​a​r​ ​b​u​t​t​o​n​ ​i​t​e​m​ ​f​r​o​m​ ​t​h​e​ ​c​u​r​r​e​n​t​ ​v​i​e​w​ ​c​o​n​t​r​o​l​l​e​r​'​s​ ​n​a​v​ ​i​t​e​m​
 ​ ​ ​ ​[​c​u​r​r​e​n​t​V​C​I​t​e​m​ ​s​e​t​L​e​f​t​B​a​r​B​u​t​t​o​n​I​t​e​m​:​n​i​l​]​;​
}​

Whenever the user switches between the two different views, you will invoke this method. Because this method references the current detail view controller, it must be called before the split view controller is updated with a new set of view controllers. In ListViewController.m, invoke this method near the top of showInfo:.

-​ ​(​v​o​i​d​)​s​h​o​w​I​n​f​o​:​(​i​d​)​s​e​n​d​e​r​
{​
 ​ ​ ​ ​C​h​a​n​n​e​l​V​i​e​w​C​o​n​t​r​o​l​l​e​r​ ​*​c​h​a​n​n​e​l​V​i​e​w​C​o​n​t​r​o​l​l​e​r​ ​=​
 ​ ​ ​ ​ ​ ​ ​ ​[​[​[​C​h​a​n​n​e​l​V​i​e​w​C​o​n​t​r​o​l​l​e​r​ ​a​l​l​o​c​]​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​i​n​i​t​W​i​t​h​S​t​y​l​e​:​U​I​T​a​b​l​e​V​i​e​w​S​t​y​l​e​G​r​o​u​p​e​d​]​ ​a​u​t​o​r​e​l​e​a​s​e​]​;​

 ​ ​ ​ ​i​f​ ​(​[​s​e​l​f​ ​s​p​l​i​t​V​i​e​w​C​o​n​t​r​o​l​l​e​r​]​)​
 ​ ​ ​ ​{​
 ​ ​ ​ ​ ​ ​ ​ ​[​s​e​l​f​ ​t​r​a​n​s​f​e​r​B​a​r​B​u​t​t​o​n​T​o​V​i​e​w​C​o​n​t​r​o​l​l​e​r​:​c​h​a​n​n​e​l​V​i​e​w​C​o​n​t​r​o​l​l​e​r​]​;​

 ​ ​ ​ ​ ​ ​ ​ ​U​I​N​a​v​i​g​a​t​i​o​n​C​o​n​t​r​o​l​l​e​r​ ​*​n​v​c​ ​=​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​[​[​U​I​N​a​v​i​g​a​t​i​o​n​C​o​n​t​r​o​l​l​e​r​ ​a​l​l​o​c​]​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​i​n​i​t​W​i​t​h​R​o​o​t​V​i​e​w​C​o​n​t​r​o​l​l​e​r​:​c​h​a​n​n​e​l​V​i​e​w​C​o​n​t​r​o​l​l​e​r​]​;​

Now do the same going the other way. In ListViewController.m, locate the tableView:didSelectRowAtIndexPath: method and add the following code:

-​ ​(​v​o​i​d​)​t​a​b​l​e​V​i​e​w​:​(​U​I​T​a​b​l​e​V​i​e​w​ ​*​)​t​a​b​l​e​V​i​e​w​
 ​ ​ ​ ​d​i​d​S​e​l​e​c​t​R​o​w​A​t​I​n​d​e​x​P​a​t​h​:​(​N​S​I​n​d​e​x​P​a​t​h​ ​*​)​i​n​d​e​x​P​a​t​h​
{​
 ​ ​ ​ ​i​f​ ​(​!​[​s​e​l​f​ ​s​p​l​i​t​V​i​e​w​C​o​n​t​r​o​l​l​e​r​]​)​
 ​ ​ ​ ​ ​ ​ ​ ​[​[​s​e​l​f​ ​n​a​v​i​g​a​t​i​o​n​C​o​n​t​r​o​l​l​e​r​]​ ​p​u​s​h​V​i​e​w​C​o​n​t​r​o​l​l​e​r​:​w​e​b​V​i​e​w​C​o​n​t​r​o​l​l​e​r​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​a​n​i​m​a​t​e​d​:​Y​E​S​]​;​
 ​ ​ ​ ​e​l​s​e​ ​{​
 ​ ​ ​ ​ ​ ​ ​ ​[​s​e​l​f​ ​t​r​a​n​s​f​e​r​B​a​r​B​u​t​t​o​n​T​o​V​i​e​w​C​o​n​t​r​o​l​l​e​r​:​w​e​b​V​i​e​w​C​o​n​t​r​o​l​l​e​r​]​;​

 ​ ​ ​ ​ ​ ​ ​ ​U​I​N​a​v​i​g​a​t​i​o​n​C​o​n​t​r​o​l​l​e​r​ ​*​n​a​v​ ​=​
 ​ ​ ​ ​ ​ ​ ​ ​[​[​U​I​N​a​v​i​g​a​t​i​o​n​C​o​n​t​r​o​l​l​e​r​ ​a​l​l​o​c​]​ ​i​n​i​t​W​i​t​h​R​o​o​t​V​i​e​w​C​o​n​t​r​o​l​l​e​r​:​w​e​b​V​i​e​w​C​o​n​t​r​o​l​l​e​r​]​;​

Build and run the application. The List button should now always appear in portrait mode – no matter what the user does – and never appear in landscape mode.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.9.197