From f2de2d7c1b417e89c1ba57a9469db9d52ec146f9 Mon Sep 17 00:00:00 2001 From: Mark Lilback Date: Fri, 20 Jul 2012 16:39:34 -0400 Subject: [PATCH] renamed classes, enforce size constraints, removed nibs --- CustomSplitView.xcodeproj/project.pbxproj | 41 ++-- .../UserInterfaceState.xcuserstate | Bin 21648 -> 27970 bytes .../AMResizableSplitViewController.h | 34 +++ .../AMResizableSplitViewController.m | 215 ++++++++++++++++++ CustomSplitView/AMResizableSplitterView.h | 19 ++ CustomSplitView/AMResizableSplitterView.m | 108 +++++++++ CustomSplitView/AppDelegate.h | 4 +- CustomSplitView/AppDelegate.m | 5 +- CustomSplitView/SplitterView.h | 26 --- CustomSplitView/SplitterView.m | 61 ----- CustomSplitView/ViewController.h | 17 -- CustomSplitView/ViewController.m | 180 --------------- CustomSplitView/en.lproj/ViewController.xib | 130 ----------- 13 files changed, 398 insertions(+), 442 deletions(-) create mode 100644 CustomSplitView/AMResizableSplitViewController.h create mode 100644 CustomSplitView/AMResizableSplitViewController.m create mode 100644 CustomSplitView/AMResizableSplitterView.h create mode 100644 CustomSplitView/AMResizableSplitterView.m delete mode 100644 CustomSplitView/SplitterView.h delete mode 100644 CustomSplitView/SplitterView.m delete mode 100644 CustomSplitView/ViewController.h delete mode 100644 CustomSplitView/ViewController.m delete mode 100644 CustomSplitView/en.lproj/ViewController.xib diff --git a/CustomSplitView.xcodeproj/project.pbxproj b/CustomSplitView.xcodeproj/project.pbxproj index 56aa35f..6a11dbd 100644 --- a/CustomSplitView.xcodeproj/project.pbxproj +++ b/CustomSplitView.xcodeproj/project.pbxproj @@ -13,13 +13,13 @@ 08DF3D1B15B898C5000A339D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 08DF3D1915B898C5000A339D /* InfoPlist.strings */; }; 08DF3D1D15B898C5000A339D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 08DF3D1C15B898C5000A339D /* main.m */; }; 08DF3D2115B898C5000A339D /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 08DF3D2015B898C5000A339D /* AppDelegate.m */; }; - 08DF3D2415B898C5000A339D /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 08DF3D2315B898C5000A339D /* ViewController.m */; }; - 08DF3D2715B898C5000A339D /* ViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 08DF3D2515B898C5000A339D /* ViewController.xib */; }; + 08DF3D2415B898C5000A339D /* AMResizableSplitViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 08DF3D2315B898C5000A339D /* AMResizableSplitViewController.m */; }; 08DF3D3015B898F3000A339D /* ImageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 08DF3D2E15B898F3000A339D /* ImageViewController.m */; }; 08DF3D3115B898F3000A339D /* ImageViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 08DF3D2F15B898F3000A339D /* ImageViewController.xib */; }; 08DF3D3315B89D32000A339D /* pdolls.png in Resources */ = {isa = PBXBuildFile; fileRef = 08DF3D3215B89D32000A339D /* pdolls.png */; }; 08DF3D3515B89D7B000A339D /* background.png in Resources */ = {isa = PBXBuildFile; fileRef = 08DF3D3415B89D7B000A339D /* background.png */; }; - 08DF3D3815B8A112000A339D /* SplitterView.m in Sources */ = {isa = PBXBuildFile; fileRef = 08DF3D3715B8A112000A339D /* SplitterView.m */; }; + 08DF3D3815B8A112000A339D /* AMResizableSplitterView.m in Sources */ = {isa = PBXBuildFile; fileRef = 08DF3D3715B8A112000A339D /* AMResizableSplitterView.m */; }; + 08DF3D3F15B9F095000A339D /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08DF3D3E15B9F095000A339D /* QuartzCore.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -33,16 +33,16 @@ 08DF3D1E15B898C5000A339D /* CustomSplitView-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CustomSplitView-Prefix.pch"; sourceTree = ""; }; 08DF3D1F15B898C5000A339D /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 08DF3D2015B898C5000A339D /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 08DF3D2215B898C5000A339D /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; - 08DF3D2315B898C5000A339D /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; - 08DF3D2615B898C5000A339D /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController.xib; sourceTree = ""; }; + 08DF3D2215B898C5000A339D /* AMResizableSplitViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AMResizableSplitViewController.h; sourceTree = ""; }; + 08DF3D2315B898C5000A339D /* AMResizableSplitViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AMResizableSplitViewController.m; sourceTree = ""; }; 08DF3D2D15B898F3000A339D /* ImageViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageViewController.h; sourceTree = ""; }; 08DF3D2E15B898F3000A339D /* ImageViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImageViewController.m; sourceTree = ""; }; 08DF3D2F15B898F3000A339D /* ImageViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ImageViewController.xib; sourceTree = ""; }; 08DF3D3215B89D32000A339D /* pdolls.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = pdolls.png; sourceTree = ""; }; 08DF3D3415B89D7B000A339D /* background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = background.png; sourceTree = ""; }; - 08DF3D3615B8A112000A339D /* SplitterView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SplitterView.h; sourceTree = ""; }; - 08DF3D3715B8A112000A339D /* SplitterView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SplitterView.m; sourceTree = ""; }; + 08DF3D3615B8A112000A339D /* AMResizableSplitterView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMResizableSplitterView.h; sourceTree = ""; }; + 08DF3D3715B8A112000A339D /* AMResizableSplitterView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMResizableSplitterView.m; sourceTree = ""; }; + 08DF3D3E15B9F095000A339D /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -50,6 +50,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 08DF3D3F15B9F095000A339D /* QuartzCore.framework in Frameworks */, 08DF3D1115B898C5000A339D /* UIKit.framework in Frameworks */, 08DF3D1315B898C5000A339D /* Foundation.framework in Frameworks */, 08DF3D1515B898C5000A339D /* CoreGraphics.framework in Frameworks */, @@ -79,6 +80,7 @@ 08DF3D0F15B898C5000A339D /* Frameworks */ = { isa = PBXGroup; children = ( + 08DF3D3E15B9F095000A339D /* QuartzCore.framework */, 08DF3D1015B898C5000A339D /* UIKit.framework */, 08DF3D1215B898C5000A339D /* Foundation.framework */, 08DF3D1415B898C5000A339D /* CoreGraphics.framework */, @@ -91,11 +93,10 @@ children = ( 08DF3D1F15B898C5000A339D /* AppDelegate.h */, 08DF3D2015B898C5000A339D /* AppDelegate.m */, - 08DF3D2215B898C5000A339D /* ViewController.h */, - 08DF3D2315B898C5000A339D /* ViewController.m */, - 08DF3D2515B898C5000A339D /* ViewController.xib */, - 08DF3D3615B8A112000A339D /* SplitterView.h */, - 08DF3D3715B8A112000A339D /* SplitterView.m */, + 08DF3D2215B898C5000A339D /* AMResizableSplitViewController.h */, + 08DF3D2315B898C5000A339D /* AMResizableSplitViewController.m */, + 08DF3D3615B8A112000A339D /* AMResizableSplitterView.h */, + 08DF3D3715B8A112000A339D /* AMResizableSplitterView.m */, 08DF3D2D15B898F3000A339D /* ImageViewController.h */, 08DF3D2E15B898F3000A339D /* ImageViewController.m */, 08DF3D2F15B898F3000A339D /* ImageViewController.xib */, @@ -169,7 +170,6 @@ buildActionMask = 2147483647; files = ( 08DF3D1B15B898C5000A339D /* InfoPlist.strings in Resources */, - 08DF3D2715B898C5000A339D /* ViewController.xib in Resources */, 08DF3D3115B898F3000A339D /* ImageViewController.xib in Resources */, 08DF3D3315B89D32000A339D /* pdolls.png in Resources */, 08DF3D3515B89D7B000A339D /* background.png in Resources */, @@ -185,9 +185,9 @@ files = ( 08DF3D1D15B898C5000A339D /* main.m in Sources */, 08DF3D2115B898C5000A339D /* AppDelegate.m in Sources */, - 08DF3D2415B898C5000A339D /* ViewController.m in Sources */, + 08DF3D2415B898C5000A339D /* AMResizableSplitViewController.m in Sources */, 08DF3D3015B898F3000A339D /* ImageViewController.m in Sources */, - 08DF3D3815B8A112000A339D /* SplitterView.m in Sources */, + 08DF3D3815B8A112000A339D /* AMResizableSplitterView.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -202,14 +202,6 @@ name = InfoPlist.strings; sourceTree = ""; }; - 08DF3D2515B898C5000A339D /* ViewController.xib */ = { - isa = PBXVariantGroup; - children = ( - 08DF3D2615B898C5000A339D /* en */, - ); - name = ViewController.xib; - sourceTree = ""; - }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ @@ -305,6 +297,7 @@ 08DF3D2C15B898C5000A339D /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/CustomSplitView.xcodeproj/project.xcworkspace/xcuserdata/mlilback.xcuserdatad/UserInterfaceState.xcuserstate b/CustomSplitView.xcodeproj/project.xcworkspace/xcuserdata/mlilback.xcuserdatad/UserInterfaceState.xcuserstate index 895f3e9677e27c0e4bc1142f6a9a013fe4bc3ab7..d652e1fe3984770c86f056f1c46b656d1471f3cf 100644 GIT binary patch literal 27970 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

=@CxGZOPcP(ICd9IaaUwY} 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 + +@class AMResizableSplitterView; + +@interface AMResizableSplitViewController : UIViewController + +//the view controllers displayed in the split view +@property (nonatomic) UIViewController *controller1; +@property (nonatomic) UIViewController *controller2; + +//the splitter view +@property (nonatomic) AMResizableSplitterView *splitterView; + +//the midpoint of the splitter view (x/y depending on orientation) +@property (nonatomic) CGFloat splitterPosition; + +//the minimum size (width used when landscape, height used when portrait) for the first view. default is 100, 100 +@property (nonatomic) CGSize minimumView1Size; + +//the minimum size (width used when landscape, height used when portrait) for the second view. default is 100, 100 +@property (nonatomic) CGSize minimumView2Size; + +// designated initializer +-(id)init; + +-(void)setSplitterPosition:(CGFloat)splitterPosition animated:(BOOL)animated; +@end diff --git a/CustomSplitView/AMResizableSplitViewController.m b/CustomSplitView/AMResizableSplitViewController.m new file mode 100644 index 0000000..88eef81 --- /dev/null +++ b/CustomSplitView/AMResizableSplitViewController.m @@ -0,0 +1,215 @@ +// +// AMResizableSplitViewController.m +// +// Created by Mark Lilback on 7/19/12. +// Copyright (c) 2012 Agile Monks, LLC. All rights reserved. +// + +#import "AMResizableSplitViewController.h" +#import "AMResizableSplitterView.h" + +#define SPLITTER_LENGTH 20 + +#pragma mark - class extension +@interface AMResizableSplitViewController () { + BOOL _handlingMove; +} +@property (nonatomic) UIView *view1; +@property (nonatomic) UIView *view2; +@end + +#pragma mark - implementation + +@implementation AMResizableSplitViewController + +-(id)init +{ + if ((self = [super init])) { + self.minimumView1Size = CGSizeMake(100, 100); + self.minimumView2Size = CGSizeMake(100, 100); + } + return self; +} + +#pragma mark - UIViewController overrides + +-(void)loadView +{ + UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 768, 1024)]; + view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; + view.autoresizesSubviews=NO; + self.view = view; +} + +-(void)viewDidLoad +{ + [super viewDidLoad]; + // Do any additional setup after loading the view, typically from a nib. + self.splitterView = [[AMResizableSplitterView alloc] initWithFrame:CGRectMake(502, 0, SPLITTER_LENGTH, 748)]; + self.splitterView.delegate = self; + [self.view addSubview:self.splitterView]; +} + +-(void)viewDidAppear:(BOOL)animated +{ + [super viewDidAppear:animated]; + [self adjustToDefaultFrames]; +} + +-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration +{ + [UIView animateWithDuration:duration animations:^{ + [self rotateChildren:toInterfaceOrientation]; + }]; +} + +#pragma mark - meat & potatos + +-(void)rotateChildren:(UIInterfaceOrientation)destOrientation +{ + BOOL toLand = UIInterfaceOrientationIsLandscape(destOrientation); + CGRect dividerFrame = self.splitterView.frame; + CGRect r1 = self.controller1.view.frame; + CGRect r2 = self.controller2.view.frame; + //adjust view1's frame + CGFloat tmp = r1.size.height; + r1.size.height = r1.size.width; + r1.size.width = tmp; + //adjust splitter's frame + tmp = dividerFrame.origin.y; + dividerFrame.origin.y = dividerFrame.origin.x; + dividerFrame.origin.x = tmp; + tmp = dividerFrame.size.height; + dividerFrame.size.height = dividerFrame.size.width; + dividerFrame.size.width = tmp; + //adjust view2's frame + tmp = r2.origin.y; + r2.origin.y = r2.origin.x; + r2.origin.x = tmp; + tmp = r2.size.height; + r2.size.height = r2.size.width; + r2.size.width = tmp; + //adjust rects for status bar height + if (toLand) { + r1.size.height -= 20; + r2.size.height -= 20; + dividerFrame.size.height -= 20; + } else { + r1.size.width += 20; + r2.size.width += 20; + dividerFrame.size.width += 20; + } + //set the frames + self.splitterView.frame = dividerFrame; + self.controller1.view.frame = r1; + self.controller2.view.frame = r2; +} + +-(void)adjustToDefaultFrames +{ + if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) { + self.controller1.view.frame = CGRectMake(0, 0, 502, 748); + self.controller2.view.frame = CGRectMake(522, 0, 502, 748); + self.splitterView.frame = CGRectMake(502, 0, SPLITTER_LENGTH, 748); + } else { + self.controller1.view.frame = CGRectMake(0, 0, 768, 502); + self.controller2.view.frame = CGRectMake(0, 522, 768, 502); + self.splitterView.frame = CGRectMake(0, 502, 768, SPLITTER_LENGTH); + } +} + +-(void)splitterView:(AMResizableSplitterView*)splitterView moveByOffset:(CGFloat)offset +{ + BOOL isLand = UIInterfaceOrientationIsLandscape(self.interfaceOrientation); + CGRect dividerRect = splitterView.frame; + + //validate the offset is in the acceptable range + CGFloat curLoc = isLand ? self.splitterView.frame.origin.x : self.splitterView.frame.origin.y; + CGFloat newLoc = curLoc + offset; + CGFloat minOffset = isLand ? self.minimumView1Size.width : self.minimumView1Size.height; + CGFloat maxOffset = isLand ? self.view.bounds.size.width : self.view.bounds.size.height; + maxOffset -= isLand ? self.minimumView2Size.width : self.minimumView2Size.height; + if (newLoc < minOffset) + offset = 0; + if (newLoc > maxOffset) + offset = maxOffset - curLoc; + if (offset == 0) + return; + + CGRect r1 = self.controller1.view.frame; + CGRect r2 = self.controller2.view.frame; + if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) { + dividerRect.origin.x = dividerRect.origin.x + offset; + r1.size.width += offset; + r2.origin.x += offset; + r2.size.width = self.view.bounds.size.width - r2.origin.x; + } else { + dividerRect.origin.y = dividerRect.origin.y + offset; + r1.size.height += offset; + r2.origin.y += offset; + r2.size.height = self.view.bounds.size.height - r2.origin.y; + } + splitterView.frame = dividerRect; + self.controller1.view.frame = r1; + self.controller2.view.frame = r2; + + [self.view setNeedsDisplay]; +} + +#pragma mark - accessors + +-(void)setController1:(UIViewController *)controller1 +{ + if (_controller1) { + [_controller1 willMoveToParentViewController:nil]; + [_controller1.view removeFromSuperview]; + [_controller1 removeFromParentViewController]; + } + _controller1 = controller1; + [self addChildViewController:controller1]; + [self.view addSubview:controller1.view]; + [controller1 didMoveToParentViewController:self]; +} + +-(void)setController2:(UIViewController *)controller2 +{ + if (_controller2) { + [_controller2 willMoveToParentViewController:nil]; + [_controller2.view removeFromSuperview]; + [_controller2 removeFromParentViewController]; + } + _controller2 = controller2; + [self addChildViewController:controller2]; + [self.view addSubview:controller2.view]; + [controller2 didMoveToParentViewController:self]; +} + +-(CGFloat)splitterPosition +{ + if ((UIInterfaceOrientationIsLandscape(self.interfaceOrientation))) + return self.splitterView.frame.origin.x + floorf(SPLITTER_LENGTH/2); + return self.splitterView.frame.origin.y + floorf(SPLITTER_LENGTH/2); +} + +-(void)setSplitterPosition:(CGFloat)splitterPosition +{ + [self setSplitterPosition:splitterPosition animated:NO]; +} + +-(void)setSplitterPosition:(CGFloat)splitterPosition animated:(BOOL)animated +{ + CGFloat offset = splitterPosition; + if ((UIInterfaceOrientationIsLandscape(self.interfaceOrientation))) + offset -= self.splitterView.frame.origin.x; + else + offset -= self.splitterView.frame.origin.y; + [self splitterView:self.splitterView moveByOffset:offset - floorf(SPLITTER_LENGTH/2)]; +} + +@synthesize controller1=_controller1; +@synthesize controller2=_controller2; +@synthesize splitterView=_splitterView; +@synthesize minimumView1Size=_minimumView1Size; +@synthesize minimumView2Size=_minimumView2Size; + +@end diff --git a/CustomSplitView/AMResizableSplitterView.h b/CustomSplitView/AMResizableSplitterView.h new file mode 100644 index 0000000..6a7a659 --- /dev/null +++ b/CustomSplitView/AMResizableSplitterView.h @@ -0,0 +1,19 @@ +// +// AMResizableSplitterView.h +// +// Created by Mark Lilback on 7/19/12. +// Copyright (c) 2012 Agile Monks, LLC. All rights reserved. +// + +#import + +@class AMResizableSplitterView; + +@protocol AMResizableSplitterViewDelegate +-(void)splitterView:(AMResizableSplitterView*)splitterView moveByOffset:(CGFloat)offset; + +@end + +@interface AMResizableSplitterView : UIView +@property (nonatomic, weak) id delegate; +@end diff --git a/CustomSplitView/AMResizableSplitterView.m b/CustomSplitView/AMResizableSplitterView.m new file mode 100644 index 0000000..bf7ed6e --- /dev/null +++ b/CustomSplitView/AMResizableSplitterView.m @@ -0,0 +1,108 @@ +// +// AMResizableSplitterView.m +// +// Created by Mark Lilback on 7/19/12. +// Copyright (c) 2012 Agile Monks, LLC. All rights reserved. +// + +#import "AMResizableSplitterView.h" + +@interface AMResizableSplitterGripView : UIView + +@end + +@interface AMResizableSplitterView() +@property (nonatomic, weak) AMResizableSplitterGripView *gripView; +@end + +@implementation AMResizableSplitterView + +- (id)initWithFrame:(CGRect)frame +{ + if ((self = [super initWithFrame:frame])) { + self.backgroundColor = [UIColor brownColor]; + AMResizableSplitterGripView *gripView = [[AMResizableSplitterGripView alloc] initWithFrame:CGRectMake(fabs(frame.size.width/2), 2, 30, 16)]; + gripView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin; + self.gripView = gripView; + [self addSubview:gripView]; + gripView.center = CGPointMake(fabsf(self.bounds.size.width/2), fabsf(self.bounds.size.height/2)); + gripView.backgroundColor = [UIColor clearColor]; + } + return self; +} + +-(void)layoutSubviews +{ + [super layoutSubviews]; + CGRect gframe = self.gripView.frame; + CGRect frame = self.frame; + if (frame.size.width > frame.size.height) { + //portrait + gframe.size.width = 30; + gframe.size.height = 16; + } else { + gframe.size.width = 16; + gframe.size.height = 30; + } + self.gripView.frame = gframe; + self.gripView.center = CGPointMake(fabsf(self.bounds.size.width/2), fabsf(self.bounds.size.height/2)); + [self.gripView setNeedsDisplay]; +} + +-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ +} + +-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ + BOOL isLand = UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]); + CGPoint pt = [touches.anyObject locationInView:self.superview]; + CGFloat ptVal = isLand ? pt.x : pt.y; + CGFloat startVal = isLand ? self.frame.origin.x : self.frame.origin.y; + CGFloat offset = (startVal - ptVal) * -1; + [self.delegate splitterView:self moveByOffset:offset]; +} + +-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ +} + +-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event +{ +} + +@end + +@implementation AMResizableSplitterGripView + +-(void)drawRect:(CGRect)rect +{ + CGRect frame = self.frame; + CGRect sframe = self.superview.frame; + UIColor *gray = [UIColor colorWithWhite:0.4 alpha:1]; + if (sframe.size.width > sframe.size.height) { + //portrait + CGRect lineRect = CGRectMake(0, 1, frame.size.width, 1); + for (int i=0; i < 3; i++) { + [gray set]; + UIRectFill(lineRect); + lineRect.origin.y += 1; + [[UIColor whiteColor] set]; + UIRectFill(lineRect); + lineRect.origin.y += 4; + } + } else { + //landscape + CGRect lineRect = CGRectMake(1, 0, 1, frame.size.height-2); + for (int i=0; i < 3; i++) { + [gray set]; + UIRectFill(lineRect); + lineRect.origin.x += 1; + [[UIColor whiteColor] set]; + UIRectFill(lineRect); + lineRect.origin.x += 4; + } + } +} + +@end diff --git a/CustomSplitView/AppDelegate.h b/CustomSplitView/AppDelegate.h index 64b99e5..cc6ae8e 100644 --- a/CustomSplitView/AppDelegate.h +++ b/CustomSplitView/AppDelegate.h @@ -8,12 +8,12 @@ #import -@class ViewController; +@class AMResizableSplitViewController; @interface AppDelegate : UIResponder @property (strong, nonatomic) UIWindow *window; -@property (strong, nonatomic) ViewController *viewController; +@property (strong, nonatomic) AMResizableSplitViewController *viewController; @end diff --git a/CustomSplitView/AppDelegate.m b/CustomSplitView/AppDelegate.m index e39a834..caca4dd 100644 --- a/CustomSplitView/AppDelegate.m +++ b/CustomSplitView/AppDelegate.m @@ -8,7 +8,7 @@ #import "AppDelegate.h" #import "ImageViewController.h" -#import "ViewController.h" +#import "AMResizableSplitViewController.h" @implementation AppDelegate @@ -16,8 +16,9 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. - self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil]; + self.viewController = [[AMResizableSplitViewController alloc] init]; self.window.rootViewController = self.viewController; + self.viewController.minimumView2Size = CGSizeMake(200, 200); [self.window makeKeyAndVisible]; ImageViewController *i1 = [[ImageViewController alloc] init]; ImageViewController *i2 = [[ImageViewController alloc] init]; diff --git a/CustomSplitView/SplitterView.h b/CustomSplitView/SplitterView.h deleted file mode 100644 index fee85cb..0000000 --- a/CustomSplitView/SplitterView.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// SplitterView.h -// CustomSplitView -// -// Created by Mark Lilback on 7/19/12. -// Copyright (c) 2012 Agile Monks. All rights reserved. -// - -#import - -@class SplitterView; - -@protocol SplitterViewDelegate --(void)splitterView:(SplitterView*)splitterView moveByOffset:(CGFloat)offset; - -@end - -@interface SplitterView : UIView -@property (nonatomic, weak) id delegate; -//for draging while in landscape -@property CGFloat minX; -@property CGFloat maxX; -//for dragging while in portrait -@property CGFloat minY; -@property CGFloat maxY; -@end diff --git a/CustomSplitView/SplitterView.m b/CustomSplitView/SplitterView.m deleted file mode 100644 index acb6e75..0000000 --- a/CustomSplitView/SplitterView.m +++ /dev/null @@ -1,61 +0,0 @@ -// -// SplitterView.m -// CustomSplitView -// -// Created by Mark Lilback on 7/19/12. -// Copyright (c) 2012 Agile Monks. All rights reserved. -// - -#import "SplitterView.h" - -@implementation SplitterView { - BOOL _inittedRange; -} - -- (id)initWithFrame:(CGRect)frame -{ - if ((self = [super initWithFrame:frame])) { - self.backgroundColor = [UIColor brownColor]; - } - return self; -} - --(void)didMoveToSuperview -{ - if (!_inittedRange) { - if (self.maxX < 100) - self.maxX = self.superview.bounds.size.height; - if (self.maxY < 100) - self.maxY = self.superview.bounds.size.width; - _inittedRange=YES; - } -} - --(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event -{ -} - --(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event -{ - BOOL isLand = UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]); - CGFloat min = isLand ? self.minX : self.minY; - CGFloat max = isLand ? self.maxX : self.maxY; - CGPoint pt = [touches.anyObject locationInView:self.superview]; - CGFloat ptVal = isLand ? pt.x : pt.y; - CGFloat startVal = isLand ? self.frame.origin.x : self.frame.origin.y; - CGFloat offset = (startVal - ptVal) * -1; - CGFloat endVal = startVal + offset; - if (endVal < min || endVal > max) - return; - [self.delegate splitterView:self moveByOffset:offset]; -} - --(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event -{ -} - --(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event -{ -} - -@end diff --git a/CustomSplitView/ViewController.h b/CustomSplitView/ViewController.h deleted file mode 100644 index a3a39ca..0000000 --- a/CustomSplitView/ViewController.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// ViewController.h -// CustomSplitView -// -// Created by Mark Lilback on 7/19/12. -// Copyright (c) 2012 Agile Monks. All rights reserved. -// - -#import - -@interface ViewController : UIViewController -@property (nonatomic) UIViewController *controller1; -@property (nonatomic) UIViewController *controller2; -@property (nonatomic) CGFloat splitterPosition; - --(void)setSplitterPosition:(CGFloat)splitterPosition animated:(BOOL)animated; -@end diff --git a/CustomSplitView/ViewController.m b/CustomSplitView/ViewController.m deleted file mode 100644 index 55968d0..0000000 --- a/CustomSplitView/ViewController.m +++ /dev/null @@ -1,180 +0,0 @@ -// -// ViewController.m -// CustomSplitView -// -// Created by Mark Lilback on 7/19/12. -// Copyright (c) 2012 Agile Monks. All rights reserved. -// - -#import "ViewController.h" -#import "SplitterView.h" - -@interface SVCView : UIView -@end - -@interface ViewController () { - BOOL _handlingMove; -} -@property (nonatomic) SplitterView *dividerView; -@property (nonatomic) UIView *view1; -@property (nonatomic) UIView *view2; -@end - -@implementation ViewController - -- (void)viewDidLoad -{ - [super viewDidLoad]; - // Do any additional setup after loading the view, typically from a nib. - self.dividerView = [[SplitterView alloc] initWithFrame:CGRectMake(502, 0, 20, 748)]; - self.dividerView.delegate = self; - [self.view addSubview:self.dividerView]; - self.dividerView.minX = 100; - self.dividerView.minY = 100; - self.dividerView.maxX = 900; - self.dividerView.maxY = 800; -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - --(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration -{ - [UIView animateWithDuration:duration animations:^{ - [self rotateChildren:toInterfaceOrientation]; - }]; -} - --(void)rotateChildren:(UIInterfaceOrientation)destOrientation -{ - BOOL toLand = UIInterfaceOrientationIsLandscape(destOrientation); - CGRect dividerFrame = self.dividerView.frame; - CGRect r1 = self.controller1.view.frame; - CGRect r2 = self.controller2.view.frame; - //r1 always has the same adjustment -- just swap width and height - CGFloat tmp = r1.size.height; - r1.size.height = r1.size.width; - r1.size.width = tmp; - tmp = dividerFrame.origin.y; - dividerFrame.origin.y = dividerFrame.origin.x; - dividerFrame.origin.x = tmp; - tmp = dividerFrame.size.height; - dividerFrame.size.height = dividerFrame.size.width; - dividerFrame.size.width = tmp; - tmp = r2.origin.y; - r2.origin.y = r2.origin.x; - r2.origin.x = tmp; - tmp = r2.size.height; - r2.size.height = r2.size.width; - r2.size.width = tmp; - if (toLand) { - r1.size.height -= 20; - r2.size.height -= 20; - dividerFrame.size.height -= 20; - } else { - r1.size.width += 20; - r2.size.width += 20; - dividerFrame.size.width += 20; - } - self.dividerView.frame = dividerFrame; - self.controller1.view.frame = r1; - self.controller2.view.frame = r2; -} - --(void)adjustToDefaultFrames -{ - if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) - [self adjustforLandscape]; - else - [self adjustForPortrait]; -} - --(void)adjustForPortrait -{ - self.controller1.view.frame = CGRectMake(0, 0, 768, 502); - self.controller2.view.frame = CGRectMake(0, 522, 768, 502); - self.dividerView.frame = CGRectMake(0, 502, 768, 20); -} - --(void)adjustforLandscape -{ - self.controller1.view.frame = CGRectMake(0, 0, 502, 748); - self.controller2.view.frame = CGRectMake(522, 0, 502, 748); - self.dividerView.frame = CGRectMake(502, 0, 20, 748); -} - - --(void)viewDidAppear:(BOOL)animated -{ - [super viewDidAppear:animated]; - [self adjustToDefaultFrames]; -} - --(void)splitterView:(SplitterView*)splitterView moveByOffset:(CGFloat)offset -{ - CGRect dividerRect = splitterView.frame; - - CGRect r1 = self.controller1.view.frame; - CGRect r2 = self.controller2.view.frame; - if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) { - dividerRect.origin.x = dividerRect.origin.x + offset; - r1.size.width += offset; - r2.origin.x += offset; - r2.size.width = self.view.bounds.size.width - r2.origin.x; - } else { - dividerRect.origin.y = dividerRect.origin.y + offset; - r1.size.height += offset; - r2.origin.y += offset; - r2.size.height = self.view.bounds.size.height - r2.origin.y; - } - splitterView.frame = dividerRect; - self.controller1.view.frame = r1; - self.controller2.view.frame = r2; - - [self.view setNeedsDisplay]; -} - --(void)setController1:(UIViewController *)controller1 -{ - if (_controller1) { - [_controller1 willMoveToParentViewController:nil]; - [_controller1.view removeFromSuperview]; - [_controller1 removeFromParentViewController]; - } - _controller1 = controller1; - [self addChildViewController:controller1]; - [self.view addSubview:controller1.view]; - [controller1 didMoveToParentViewController:self]; -} - --(void)setController2:(UIViewController *)controller2 -{ - if (_controller2) { - [_controller2 willMoveToParentViewController:nil]; - [_controller2.view removeFromSuperview]; - [_controller2 removeFromParentViewController]; - } - _controller2 = controller2; - [self addChildViewController:controller2]; - [self.view addSubview:controller2.view]; - [controller2 didMoveToParentViewController:self]; -} - --(void)setSplitterPosition:(CGFloat)splitterPosition animated:(BOOL)animated -{ - _splitterPosition = splitterPosition; -} - -@end - -@implementation SVCView - --(void)layoutSubviews -{ - -} - -@end diff --git a/CustomSplitView/en.lproj/ViewController.xib b/CustomSplitView/en.lproj/ViewController.xib deleted file mode 100644 index 7ff55d3..0000000 --- a/CustomSplitView/en.lproj/ViewController.xib +++ /dev/null @@ -1,130 +0,0 @@ - - - - 1536 - 11E53 - 2818 - 1138.47 - 569.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 1900 - - - IBProxyObject - IBUIView - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBIPadFramework - - - IBFirstResponder - IBIPadFramework - - - - 274 - {{0, 20}, {768, 1004}} - - - - 3 - MQA - - 2 - - - - 2 - - IBIPadFramework - - - - - - - view - - - - 3 - - - - - - 0 - - - - - - -1 - - - File's Owner - - - -2 - - - - - 2 - - - - - - - ViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - SVCView - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 3 - - - - - SVCView - UIView - - IBProjectSource - ./Classes/SVCView.h - - - - ViewController - UIViewController - - IBProjectSource - ./Classes/ViewController.h - - - - - 0 - IBIPadFramework - YES - 3 - YES - 1900 - -