Skip to content

Commit

Permalink
UI layout unification: UITypePad now uses same layout as UITypePhone (#…
Browse files Browse the repository at this point in the history
…371)

change details:
- in landscape orientation, no longer use BoardPositionToolbarController
  at the top of the screen in the left pane.
- in both portrait and landscape orientation, no longer use
  NavigationBarController with its three navigation bars faking a single
  bar.
  - in portrait orientation, instead use the single navigation bar
    provided by PlayRootViewNavigationController and populate its
    left/right bar button items, as well as integrate the status view as
    the navigation bar's title view.
  - in landscape orientation, instead display a button box with the game
    actions and the status view at the top of the screen in the left
    pane.
- extended layout support: PlayRootViewControllerPad now defines a
  background color to be shown behind the translucent bars at the top
  and bottom of the screen.
- LeftPaneViewController and RightPaneViewController are radically
  simplified because they now have to support only a single layout.
  • Loading branch information
herzbube committed Mar 26, 2022
1 parent e9d7491 commit 15c2a06
Show file tree
Hide file tree
Showing 8 changed files with 308 additions and 326 deletions.
42 changes: 42 additions & 0 deletions doc/NOTES.Design
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,48 @@ View controller hierarchy for UITypePhone:
+-- UICollectionView (game action cells)


View controller hierarchy for UITypePad:

MainTabBarController : UITabBarController
+-- PlayRootViewNavigationController : UINavigationController
+-- PlayRootViewControllerPad : PlayRootViewController
+-- Portrait orientation
| +-- StatusViewController (titleView of navigation bar of PlayRootViewNavigationController)
| | +-- UILabel
| | +-- UIActivityIndicatorView
| +-- BoardViewController
| | +-- PanGestureController
| | +-- TapGestureController
| | +-- DoubleTapGestureController
| | +-- TwoFingerTapGestureController
| | +-- BoardAnimationController
| | +-- BoardView
| +-- ButtonBoxController : UICollectionViewController
| | +-- UICollectionView (board position navigation cells)
| +-- BoardPositionCollectionViewController : UICollectionViewController
| | +-- UICollectionView (BoardPositionCollectionViewCell cells)
+-- Landscape orientation
+-- SplitViewController
+-- LeftPaneViewController
| +-- StatusViewController
| | +-- UILabel
| | +-- UIActivityIndicatorView
| +-- BoardPositionCollectionViewController : UICollectionViewController
| | +-- UICollectionView (BoardPositionCollectionViewCell cells)
+-- RightPaneViewController
+-- ButtonBoxController : UICollectionViewController
| +-- UICollectionView (board position navigation cells)
+-- BoardViewController
| +-- PanGestureController
| +-- TapGestureController
| +-- DoubleTapGestureController
| +-- TwoFingerTapGestureController
| +-- BoardAnimationController
| +-- BoardView
+-- ButtonBoxController : UICollectionViewController
+-- UICollectionView (game action cells)


iOS 7 and Auto Layout
---------------------
In iOS 7 Apple added the concept of translucent / transparent bars (tab bars,
Expand Down
3 changes: 0 additions & 3 deletions src/play/controller/NavigationBarController.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ + (NavigationBarController*) navigationBarController
case UITypePhonePortraitOnly:
navigationBarController = [[[NavigationBarControllerPhonePortraitOnly alloc] init] autorelease];
break;
case UITypePad:
navigationBarController = [[[NavigationBarControllerPhonePortraitOnly alloc] init] autorelease];
break;
default:
[ExceptionUtility throwInvalidUIType:[LayoutManager sharedManager].uiType];
navigationBarController = nil; // make compiler happy
Expand Down
2 changes: 1 addition & 1 deletion src/play/controller/StatusViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ - (void) configureViews
self.statusLabel.lineBreakMode = NSLineBreakByWordWrapping;
self.statusLabel.textAlignment = NSTextAlignmentCenter;

if ([LayoutManager sharedManager].uiType == UITypePhone)
if ([LayoutManager sharedManager].uiType != UITypePhonePortraitOnly)
{
UIInterfaceOrientation interfaceOrientation = [UiElementMetrics interfaceOrientation];
bool isPortraitOrientation = UIInterfaceOrientationIsPortrait(interfaceOrientation);
Expand Down
5 changes: 3 additions & 2 deletions src/play/rootview/PlayRootViewControllerPad.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@


// Project includes
#include "PlayRootViewController.h"
#import "PlayRootViewController.h"
#import "GameActionManager.h"


// -----------------------------------------------------------------------------
Expand All @@ -26,7 +27,7 @@
/// The PlayRootViewController class method playRootViewController() should be
/// used to create a PlayRootViewControllerPad instance.
// -----------------------------------------------------------------------------
@interface PlayRootViewControllerPad : PlayRootViewController
@interface PlayRootViewControllerPad : PlayRootViewController <GameActionManagerUIDelegate>
{
}

Expand Down
210 changes: 148 additions & 62 deletions src/play/rootview/PlayRootViewControllerPad.m

Large diffs are not rendered by default.

113 changes: 24 additions & 89 deletions src/play/splitview/LeftPaneViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
// Project includes
#import "LeftPaneViewController.h"
#import "../boardposition/BoardPositionCollectionViewController.h"
#import "../boardposition/BoardPositionToolbarController.h"
#import "../controller/StatusViewController.h"
#import "../../shared/LayoutManager.h"
#import "../../ui/AutoLayoutUtility.h"
Expand All @@ -29,9 +28,7 @@
/// @brief Class extension with private properties for LeftPaneViewController.
// -----------------------------------------------------------------------------
@interface LeftPaneViewController()
@property(nonatomic, assign) bool useBoardPositionToolbar;
@property(nonatomic, retain) BoardPositionCollectionViewController* boardPositionCollectionViewController;
@property(nonatomic, retain) BoardPositionToolbarController* boardPositionToolbarController;
@property(nonatomic, retain) StatusViewController* statusViewController;
@end

Expand All @@ -51,7 +48,6 @@ - (id) init
self = [super initWithNibName:nil bundle:nil];
if (! self)
return nil;
[self setupUseBoardPositionToolbar];
[self setupChildControllers];
return self;
}
Expand All @@ -61,66 +57,21 @@ - (id) init
// -----------------------------------------------------------------------------
- (void) dealloc
{
self.boardPositionToolbarController = nil;
self.boardPositionCollectionViewController = nil;
self.statusViewController = nil;

[super dealloc];
}

// -----------------------------------------------------------------------------
/// @brief Private helper for initializer.
// -----------------------------------------------------------------------------
- (void) setupUseBoardPositionToolbar
{
if ([LayoutManager sharedManager].uiType == UITypePhone)
self.useBoardPositionToolbar = false;
else
self.useBoardPositionToolbar = true;
}

#pragma mark - Container view controller handling

// -----------------------------------------------------------------------------
/// This is an internal helper invoked during initialization.
// -----------------------------------------------------------------------------
- (void) setupChildControllers
{
if (self.useBoardPositionToolbar)
{
self.boardPositionToolbarController = [[[BoardPositionToolbarController alloc] init] autorelease];
self.boardPositionCollectionViewController = [[[BoardPositionCollectionViewController alloc] initWithScrollDirection:UICollectionViewScrollDirectionVertical] autorelease];
}
else
{
self.boardPositionCollectionViewController = [[[BoardPositionCollectionViewController alloc] initWithScrollDirection:UICollectionViewScrollDirectionVertical] autorelease];
self.statusViewController = [[[StatusViewController alloc] init] autorelease];
}
}

// -----------------------------------------------------------------------------
/// @brief Private setter implementation.
// -----------------------------------------------------------------------------
- (void) setBoardPositionToolbarController:(BoardPositionToolbarController*)boardPositionToolbarController
{
if (_boardPositionToolbarController == boardPositionToolbarController)
return;
if (_boardPositionToolbarController)
{
[_boardPositionToolbarController willMoveToParentViewController:nil];
// Automatically calls didMoveToParentViewController:
[_boardPositionToolbarController removeFromParentViewController];
[_boardPositionToolbarController release];
_boardPositionToolbarController = nil;
}
if (boardPositionToolbarController)
{
// Automatically calls willMoveToParentViewController:
[self addChildViewController:boardPositionToolbarController];
[boardPositionToolbarController didMoveToParentViewController:self];
[boardPositionToolbarController retain];
_boardPositionToolbarController = boardPositionToolbarController;
}
self.boardPositionCollectionViewController = [[[BoardPositionCollectionViewController alloc] initWithScrollDirection:UICollectionViewScrollDirectionVertical] autorelease];
self.statusViewController = [[[StatusViewController alloc] init] autorelease];
}

// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -182,46 +133,30 @@ - (void) loadView
{
[super loadView];

[self.view addSubview:self.statusViewController.view];
[self.view addSubview:self.boardPositionCollectionViewController.view];

self.statusViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
self.boardPositionCollectionViewController.view.translatesAutoresizingMaskIntoConstraints = NO;

NSMutableDictionary* viewsDictionary = [NSMutableDictionary dictionary];
NSMutableArray* visualFormats = [NSMutableArray array];

if (self.useBoardPositionToolbar)
{
[self.view addSubview:self.boardPositionToolbarController.view];
[self.view addSubview:self.boardPositionCollectionViewController.view];
self.boardPositionToolbarController.view.translatesAutoresizingMaskIntoConstraints = NO;
self.boardPositionCollectionViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
viewsDictionary[@"boardPositionToolbar"] = self.boardPositionToolbarController.view;
viewsDictionary[@"boardPositionCollectionView"] = self.boardPositionCollectionViewController.view;
[visualFormats addObject:@"H:|-0-[boardPositionToolbar]-0-|"];
[visualFormats addObject:@"H:|-0-[boardPositionCollectionView]-0-|"];
// Don't need to specify a height value for boardPositionToolbar because
// UIToolbar specifies a height value in its intrinsic content size
[visualFormats addObject:@"V:|-0-[boardPositionToolbar]-0-[boardPositionCollectionView]-0-|"];
}
else
{
[self.view addSubview:self.statusViewController.view];
[self.view addSubview:self.boardPositionCollectionViewController.view];
self.statusViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
self.boardPositionCollectionViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
viewsDictionary[@"statusView"] = self.statusViewController.view;
viewsDictionary[@"boardPositionCollectionView"] = self.boardPositionCollectionViewController.view;
// Let the subviews extend all the way to the left/right edges of our view.
// The child view controllers take care of the safe area handling.
[visualFormats addObject:@"H:|-0-[statusView]-0-|"];
[visualFormats addObject:@"H:|-0-[boardPositionCollectionView]-0-|"];
[visualFormats addObject:@"V:|-0-[statusView]-0-[boardPositionCollectionView]-0-|"];

// This multiplier was experimentally determined so that even with 4 lines
// of text there is a comfortable spacing at the top/bottom of the status
// view label. The multiplier is closely linked to the label's font size.
CGFloat statusViewContentHeightMultiplier = 1.4f;
int statusViewContentHeight = [UiElementMetrics tableViewCellContentViewHeight] * statusViewContentHeightMultiplier;
// Here we define the statusView height, and by consequence the height of
// the boardPositionCollectionView.
[visualFormats addObject:[NSString stringWithFormat:@"V:[statusView(==%d)]", statusViewContentHeight]];
}
viewsDictionary[@"statusView"] = self.statusViewController.view;
viewsDictionary[@"boardPositionCollectionView"] = self.boardPositionCollectionViewController.view;
// Let the subviews extend all the way to the left/right edges of our view.
// The child view controllers take care of the safe area handling.
[visualFormats addObject:@"H:|-0-[statusView]-0-|"];
[visualFormats addObject:@"H:|-0-[boardPositionCollectionView]-0-|"];
[visualFormats addObject:@"V:|-0-[statusView]-0-[boardPositionCollectionView]-0-|"];

// This multiplier was experimentally determined so that even with 4 lines
// of text there is a comfortable spacing at the top/bottom of the status
// view label. The multiplier is closely linked to the label's font size.
CGFloat statusViewContentHeightMultiplier = 1.4f;
int statusViewContentHeight = [UiElementMetrics tableViewCellContentViewHeight] * statusViewContentHeightMultiplier;
// Here we define the statusView height, and by consequence the height of
// the boardPositionCollectionView.
[visualFormats addObject:[NSString stringWithFormat:@"V:[statusView(==%d)]", statusViewContentHeight]];

[AutoLayoutUtility installVisualFormats:visualFormats withViews:viewsDictionary inView:self.view];
}
Expand Down
5 changes: 0 additions & 5 deletions src/play/splitview/RightPaneViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
// Project includes
#import "../../ui/ButtonBoxController.h"

// Forward declarations
@class NavigationBarController;


// -----------------------------------------------------------------------------
/// @brief The RightPaneViewController class manages a simple container view
Expand All @@ -34,6 +31,4 @@
{
}

@property(nonatomic, retain) NavigationBarController* navigationBarController;

@end
Loading

0 comments on commit 15c2a06

Please sign in to comment.