Commit 6f5233ac authored by Eloy Duran's avatar Eloy Duran

Import MGSplitViewController example from https://github.com/mattgemmell/MGSplitViewController.

parent 3e234991
*.pbxuser
*.perspectivev3
build
//
// DetailViewController.h
// MGSplitView
//
// Created by Matt Gemmell on 26/07/2010.
// Copyright Instinctive Code 2010.
//
#import <UIKit/UIKit.h>
#import "MGSplitViewController.h"
@interface DetailViewController : UIViewController <UIPopoverControllerDelegate, MGSplitViewControllerDelegate> {
IBOutlet MGSplitViewController *splitController;
IBOutlet UIBarButtonItem *toggleItem;
IBOutlet UIBarButtonItem *verticalItem;
IBOutlet UIBarButtonItem *dividerStyleItem;
IBOutlet UIBarButtonItem *masterBeforeDetailItem;
UIPopoverController *popoverController;
UIToolbar *toolbar;
id detailItem;
UILabel *detailDescriptionLabel;
}
@property (nonatomic, retain) IBOutlet UIToolbar *toolbar;
@property (nonatomic, retain) id detailItem;
@property (nonatomic, retain) IBOutlet UILabel *detailDescriptionLabel;
- (IBAction)toggleMasterView:(id)sender;
- (IBAction)toggleVertical:(id)sender;
- (IBAction)toggleDividerStyle:(id)sender;
- (IBAction)toggleMasterBeforeDetail:(id)sender;
@end
//
// DetailViewController.m
// MGSplitView
//
// Created by Matt Gemmell on 26/07/2010.
// Copyright Instinctive Code 2010.
//
#import "DetailViewController.h"
#import "RootViewController.h"
@interface DetailViewController ()
@property (nonatomic, retain) UIPopoverController *popoverController;
- (void)configureView;
@end
@implementation DetailViewController
@synthesize toolbar, popoverController, detailItem, detailDescriptionLabel;
#pragma mark -
#pragma mark Managing the detail item
// When setting the detail item, update the view and dismiss the popover controller if it's showing.
- (void)setDetailItem:(id)newDetailItem
{
if (detailItem != newDetailItem) {
[detailItem release];
detailItem = [newDetailItem retain];
// Update the view.
[self configureView];
}
if (popoverController != nil) {
[popoverController dismissPopoverAnimated:YES];
}
}
- (void)configureView
{
// Update the user interface for the detail item.
detailDescriptionLabel.text = [detailItem description];
toggleItem.title = ([splitController isShowingMaster]) ? @"Hide Master" : @"Show Master"; // "I... AM... THE MASTER!" Derek Jacobi. Gave me chills.
verticalItem.title = (splitController.vertical) ? @"Horizontal Split" : @"Vertical Split";
dividerStyleItem.title = (splitController.dividerStyle == MGSplitViewDividerStyleThin) ? @"Enable Dragging" : @"Disable Dragging";
masterBeforeDetailItem.title = (splitController.masterBeforeDetail) ? @"Detail First" : @"Master First";
}
#pragma mark -
#pragma mark Split view support
- (void)splitViewController:(MGSplitViewController*)svc
willHideViewController:(UIViewController *)aViewController
withBarButtonItem:(UIBarButtonItem*)barButtonItem
forPopoverController: (UIPopoverController*)pc
{
//NSLog(@"%@", NSStringFromSelector(_cmd));
if (barButtonItem) {
barButtonItem.title = @"Popover";
NSMutableArray *items = [[toolbar items] mutableCopy];
[items insertObject:barButtonItem atIndex:0];
[toolbar setItems:items animated:YES];
[items release];
}
self.popoverController = pc;
}
// Called when the view is shown again in the split view, invalidating the button and popover controller.
- (void)splitViewController:(MGSplitViewController*)svc
willShowViewController:(UIViewController *)aViewController
invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
//NSLog(@"%@", NSStringFromSelector(_cmd));
if (barButtonItem) {
NSMutableArray *items = [[toolbar items] mutableCopy];
[items removeObject:barButtonItem];
[toolbar setItems:items animated:YES];
[items release];
}
self.popoverController = nil;
}
- (void)splitViewController:(MGSplitViewController*)svc
popoverController:(UIPopoverController*)pc
willPresentViewController:(UIViewController *)aViewController
{
//NSLog(@"%@", NSStringFromSelector(_cmd));
}
- (void)splitViewController:(MGSplitViewController*)svc willChangeSplitOrientationToVertical:(BOOL)isVertical
{
//NSLog(@"%@", NSStringFromSelector(_cmd));
}
- (void)splitViewController:(MGSplitViewController*)svc willMoveSplitToPosition:(float)position
{
//NSLog(@"%@", NSStringFromSelector(_cmd));
}
- (float)splitViewController:(MGSplitViewController *)svc constrainSplitPosition:(float)proposedPosition splitViewSize:(CGSize)viewSize
{
//NSLog(@"%@", NSStringFromSelector(_cmd));
return proposedPosition;
}
#pragma mark -
#pragma mark Actions
- (IBAction)toggleMasterView:(id)sender
{
[splitController toggleMasterView:sender];
[self configureView];
}
- (IBAction)toggleVertical:(id)sender
{
[splitController toggleSplitOrientation:self];
[self configureView];
}
- (IBAction)toggleDividerStyle:(id)sender
{
MGSplitViewDividerStyle newStyle = ((splitController.dividerStyle == MGSplitViewDividerStyleThin) ? MGSplitViewDividerStylePaneSplitter : MGSplitViewDividerStyleThin);
[splitController setDividerStyle:newStyle animated:YES];
[self configureView];
}
- (IBAction)toggleMasterBeforeDetail:(id)sender
{
[splitController toggleMasterBeforeDetail:sender];
[self configureView];
}
#pragma mark -
#pragma mark Rotation support
// Ensure that the view controller supports rotation and that the split view can therefore show in both portrait and landscape.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[self configureView];
}
- (void)dealloc
{
[popoverController release];
[toolbar release];
[detailItem release];
[detailDescriptionLabel release];
[super dealloc];
}
@end
//
// MGSplitViewAppDelegate.h
// MGSplitView
//
// Created by Matt Gemmell on 26/07/2010.
// Copyright Instinctive Code 2010.
//
#import <UIKit/UIKit.h>
@class RootViewController;
@class DetailViewController;
@class MGSplitViewController;
@interface MGSplitViewAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
MGSplitViewController *splitViewController;
RootViewController *rootViewController;
DetailViewController *detailViewController;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet MGSplitViewController *splitViewController;
@property (nonatomic, retain) IBOutlet RootViewController *rootViewController;
@property (nonatomic, retain) IBOutlet DetailViewController *detailViewController;
@end
//
// MGSplitViewAppDelegate.m
// MGSplitView
//
// Created by Matt Gemmell on 26/07/2010.
// Copyright Instinctive Code 2010.
//
#import "MGSplitViewAppDelegate.h"
#import "RootViewController.h"
#import "DetailViewController.h"
#import "MGSplitViewController.h"
@implementation MGSplitViewAppDelegate
@synthesize window, splitViewController, rootViewController, detailViewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Add the split view controller's view to the window and display.
[window addSubview:splitViewController.view];
[window makeKeyAndVisible];
[rootViewController performSelector:@selector(selectFirstRow) withObject:nil afterDelay:0];
[detailViewController performSelector:@selector(configureView) withObject:nil afterDelay:0];
if (NO) { // whether to allow dragging the divider to move the split.
splitViewController.splitWidth = 15.0; // make it wide enough to actually drag!
splitViewController.allowsDraggingDivider = YES;
}
return YES;
}
- (void)dealloc
{
[splitViewController release];
[window release];
[super dealloc];
}
@end
//
// RootViewController.h
// MGSplitView
//
// Created by Matt Gemmell on 26/07/2010.
// Copyright Instinctive Code 2010.
//
#import <UIKit/UIKit.h>
@class DetailViewController;
@interface RootViewController : UITableViewController {
DetailViewController *detailViewController;
}
@property (nonatomic, retain) IBOutlet DetailViewController *detailViewController;
- (void)selectFirstRow;
@end
//
// RootViewController.m
// MGSplitView
//
// Created by Matt Gemmell on 26/07/2010.
// Copyright Instinctive Code 2010.
//
#import "RootViewController.h"
#import "DetailViewController.h"
@implementation RootViewController
@synthesize detailViewController;
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.clearsSelectionOnViewWillAppear = NO;
self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0);
}
// Ensure that the view controller supports rotation and that the split view can therefore show in both portrait and landscape.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (void)selectFirstRow
{
if ([self.tableView numberOfSections] > 0 && [self.tableView numberOfRowsInSection:0] > 0) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionTop];
[self tableView:self.tableView didSelectRowAtIndexPath:indexPath];
}
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)aTableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"CellIdentifier";
// Dequeue or create a cell of the appropriate type.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
}
// Configure the cell.
cell.textLabel.text = [NSString stringWithFormat:@"Row %d", indexPath.row];
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// When a row is selected, set the detail view controller's detail item to the item associated with the selected row.
detailViewController.detailItem = [NSString stringWithFormat:@"Row %d", indexPath.row];
}
#pragma mark -
#pragma mark Memory management
- (void)dealloc
{
[detailViewController release];
[super dealloc];
}
@end
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.instinctivecode.test.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSMainNibFile</key>
<string>MainWindow</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:MGSplitView.xcodeproj">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
<FileRef
location = "group:MGSplitView.xcodeproj">
</FileRef>
</Workspace>
//
// Prefix header for all source files of the 'MGSplitView' target in the 'MGSplitView' project
//
#import <Availability.h>
#ifndef __IPHONE_3_2
#warning "This project uses features only available in iPhone SDK 3.2 and later."
#endif
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#endif
This diff is collapsed.
dependency 'MGSplitViewController', '1.0.0'
**_NOTE: This is the MGSplitViewController example from https://github.com/mattgemmell/MGSplitViewController, but only updated to use CocoaPods. It does not contain the actual source files that make up the library, because those are fetched when running: $pod install_**
MGSplitViewController
=====================
MGSplitViewController is a replacement for UISplitViewController, with various useful enhancements.
Donations
---------
I wrote MGSplitViewController for my own use, but I'm making it available (as usual) for the benefit of the iOS developer community.
If you find it useful, a Paypal donation (or something from my Amazon.co.uk Wishlist) would be very much appreciated. Appropriate links can be found here: <http://mattgemmell.com/source>
Features
--------
Please note that, since split-views are commonly used for "Master-Detail" interfaces, I call the first sub-view the "master" and the second sub-view the "detail".
- By default, MGSplitViewController mimics the appearance and (complete) behaviour of UISplitViewController, including its delegate API. It accepts two UIViewControllers (or subclasses thereof).
- Allows toggling the _visibility of the master view_ in either interface-orientation; i.e. you can have master-detail or detail-only in either landscape and/or portrait orientations (independently, and/or interactively).
- Allows choosing whether the _split orientation_ is vertical (i.e. left/right, like UISplitViewController), or horizontal (master above, and detail below). You can toggle between modes interactively, with animation.
- Allows choosing whether the master view is _before_ (above, or to left of) the detail view, or _after_ it (below, or to the right).
- Allows you to choose (and change) the _position_ of the split, i.e. the relative sizes of the master and detail views.
- Allows you to enable _dragging_ of the split/divider between the master and detail views, with optional constraining via a delegate method.
- Allows you to choose the _width of the split_ between the master and detail views.
- Preset "_divider styles_": one for non-draggable UISplitViewController-like dividers, and one for draggable, thicker style with a grip-strip.
- Allows you to substitute your own divider-view (an MGSplitDividerView subclass), used to draw the split between the master and detail views.
How to use
----------
The "MGSplitViewController.h" header file (and the sample project) should be self-explanatory. It's recommended that you use the project as a reference.
Interface Builder support
-------------------------
At time of writing, MGSplitViewController cannot be quite as elegantly _visually_ configured like UISplitViewController using Interface Builder.
You can, however, (and it is recommended that you do) create an instance of it in a xib, and connect the masterViewController and detailViewController outlets to the required view-controllers.
License and Warranty
--------------------
The license for the code is included with the project; it's basically a BSD license with attribution.
You're welcome to use it in commercial, closed-source, open source, free or any other kind of software, as long as you credit me appropriately.
The MGSplitViewController code comes with no warranty of any kind. I hope it'll be useful to you (it certainly is to me), but I make no guarantees regarding its functionality or otherwise.
Support / Contact / Bugs / Features
-----------------------------------
I can't answer any questions about how to use the code, but I always welcome emails telling me that you're using it, or just saying thanks.
If you create an app which uses the code, I'd also love to hear about it. You can find my contact details on my web site, listed below.
Likewise, if you want to submit a feature request or bug report, feel free to get in touch. Better yet, fork the code and implement the feature/fix yourself, then submit a pull request.
Enjoy the code!
Cheers,
Matt Legend Gemmell
Writing: http://mattgemmell.com/
Contact: http://mattgemmell.com/about
Twitter: http://twitter.com/mattgemmell
Hire Me: http://instinctivecode.com/
{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf320
{\fonttbl\f0\fnil\fcharset0 LucidaGrande;}
{\colortbl;\red255\green255\blue255;\red51\green51\blue51;\red0\green180\blue128;\red255\green0\blue0;
\red31\green105\blue199;\red119\green119\blue119;}
{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{decimal\}.}{\leveltext\leveltemplateid1\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\lin720 }{\listname ;}\listid1}}
{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}}
\deftab720
\pard\pardeftab720\ql\qnatural
\f0\b\fs24 \cf2 Matt Legend Gemmell / Instinctive Code Source Code License\
\b0\fs22 Last updated: 9th May 2010
\fs24 \
\
\
Thanks for downloading some of our source code!\
\
This is the license agreement for the source code which this document accompanies (don\'92t worry: you\'92re allowed to use it in your own products, commercial or otherwise).\
\
The full license text is further down this page, and you should only use the source code if you agree to the terms in that text. For convenience, though, we\'92ve put together a human-readable
\b non-authoritative
\b0 interpretation of the license which will hopefully answer any questions you have.\
\
\
\b \cf3 Green
\b0 \cf2 text shows
\b \cf3 what you can do with the code
\b0 \cf2 .\
\b \cf4 Red
\b0 \cf2 text means
\b \cf4 restrictions you must abide by
\b0 \cf2 .\
\
Basically, the license says that:\
\
\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural
\ls1\ilvl0\cf2 {\listtext 1. }You can
\b \cf3 use the code in your own products, including commercial and/or closed-source products
\b0 \cf2 .\
{\listtext 2. }You can
\b \cf3 modify the code
\b0 \cf0 as you wish\cf2 , and
\b \cf3 use the modified code in your products
\b0 \cf2 .\
{\listtext 3. }You can
\b \cf3 redistribute the original, unmodified code
\b0 \cf2 , but you
\b \cf4 have to include the full license text below
\b0 \cf2 .\
{\listtext 4. }You can
\b \cf3 redistribute the modified code
\b0 \cf2 as you wish (
\b \cf4 without the full license text below
\b0 \cf2 ).\
{\listtext 5. }In all cases, you
\b \cf4 must include a credit mentioning Matt Legend Gemmell
\b0 \cf2 as the original author of the source.\
{\listtext 6. }Matt Legend Gemmell is \cf0 not liable for anything you do with the code\cf2 , no matter what. So be sensible.\
{\listtext 7. }You
\b \cf4 can\'92t use the name Matt Legend Gemmell, the name Instinctive Code, the Instinctive Code logo or any other related marks to promote your products
\b0 \cf2 based on the code.\
{\listtext 8. }If you agree to all of that, go ahead and use the source. Otherwise, don\'92t!\
\pard\pardeftab720\ql\qnatural
\cf2 \
\b \
\
Suggested Attribution Format\
\b0 \
The license requires that you give credit to Matt Legend Gemmell, as the original author of any of our source that you use. The placement and format of the credit is up to you, but we prefer the credit to be in the software\'92s \'93About\'94 window. Alternatively, you could put the credit in a list of acknowledgements within the software, in the software\'92s documentation, or on the web page for the software. The suggested format for the attribution is:\
\
\pard\pardeftab720\ql\qnatural
\b \cf0 Includes <Name of Code> code by {\field{\*\fldinst{HYPERLINK "http://mattgemmell.com/"}}{\fldrslt \cf5 Matt Legend Gemmell}}\cf6 .
\b0 \
\pard\pardeftab720\ql\qnatural
\cf2 \
where <Name of Code> would be replaced by the name of the specific source-code package you made use of. Where possible, please link the text \'93Matt Legend Gemmell\'94 to the following URL, or include the URL as plain text: {\field{\*\fldinst{HYPERLINK "http://mattgemmell.com/"}}{\fldrslt \cf5 http://mattgemmell.com/}}\
\
\
\b Full Source Code License Text\
\
\b0 Below you can find the actual text of the license agreement.
\b \
\
\pard\pardeftab720\ql\qnatural
\cf6 \
License Agreement for Source Code provided by Matt Legend Gemmell
\b0 \
\
This software is supplied to you by Matt Legend Gemmell in consideration of your agreement to the following terms, and your use, installation, modification or redistribution of this software constitutes acceptance of these terms. If you do not agree with these terms, please do not use, install, modify or redistribute this software.\
\
In consideration of your agreement to abide by the following terms, and subject to these terms, Matt Legend Gemmell grants you a personal, non-exclusive license, to use, reproduce, modify and redistribute the software, with or without modifications, in source and/or binary forms; provided that if you redistribute the software in its entirety and without modifications, you must retain this notice and the following text and disclaimers in all such redistributions of the software, and that in all cases attribution of Matt Legend Gemmell as the original author of the source code shall be included in all such resulting software products or distributions.\uc0\u8232 \
Neither the name, trademarks, service marks or logos of Matt Legend Gemmell or Instinctive Code may be used to endorse or promote products derived from the software without specific prior written permission from Matt Legend Gemmell. Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by Matt Legend Gemmell herein, including but not limited to any patent rights that may be infringed by your derivative works or by other works in which the software may be incorporated.\
\
The software is provided by Matt Legend Gemmell on an "AS IS" basis. MATT LEGEND GEMMELL AND INSTINCTIVE CODE MAKE NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.\
\
IN NO EVENT SHALL MATT LEGEND GEMMELL OR INSTINCTIVE CODE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF MATT LEGEND GEMMELL OR INSTINCTIVE CODE HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\
}
\ No newline at end of file
TODO
====
Interface Builder
-----------------
- Support visual configuration in Interface Builder, like UISplitViewController?
//
// main.m
// MGSplitView
//
// Created by Matt Gemmell on 26/07/2010.
// Copyright Instinctive Code 2010. All rights reserved.
//
#import <UIKit/UIKit.h>
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment