原則として、非常にうまく機能するカスタム Split View Controller を実装しました。
ただし、バージョン 5.1 より前の iOS では、ツールバーのサイズ変更アニメーションが動作しないことが予想されていました — 存在する場合:
メソッドをオーバーライドするために UIToolbar をサブクラス化した後layoutSubviews
、メイン コンテンツ領域の幅の変更をアニメーション化すると、ツールバー項目が期待どおりに移動します。ただし、ツールバーの背景は期待どおりにアニメーション化されません。
代わりに、その幅はすぐに新しい値に変更され、幅を増やしながら背景が表示されます。
私が使用するコードの関連部分は次のとおりです。
// From the implementation of my Split Layout View Class:
- (void)setAuxiliaryViewHidden:(BOOL)hide animated:(BOOL)animated completion:(void (^)(BOOL isFinished))completion
{
auxiliaryViewHidden_ = hide;
if (!animated)
{
[self layoutSubviews];
if (completion)
completion(YES);
return;
}
// I've tried it with and without UIViewAnimationOptionsLayoutSubviews -- didn't change anything...
UIViewAnimationOptions easedRelayoutStartingFromCurrentState = UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionBeginFromCurrentState;
[UIView animateWithDuration:M_1_PI delay:0.0 options:easedRelayoutStartingFromCurrentState animations:^{
[self layoutSubviews];
} completion:completion];
}
- (void)layoutSubviews
{
[super layoutSubviews];
// tedious layout work to calculate the frames for the main- and auxiliary-content views
self.mainContentView.frame = mainContentFrame; // <= This currently has the toolbar, but...
self.auxiliaryContentView.frame = auxiliaryContentFrame; // ...this one could contain one, as well.
}
// The complete implementation of my UIToolbar class:
@implementation AnimatableToolbar
static CGFloat sThresholdSelectorMargin = 30.;
- (void)layoutSubviews
{
[super layoutSubviews];
// walk the subviews looking for the views that represent toolbar items
for (UIView *subview in self.subviews)
{
NSString *className = NSStringFromClass([subview class]);
if (![className hasPrefix:@"UIToolbar"]) // not a toolbar item view
continue;
if (![subview isKindOfClass:[UIControl class]]) // some other private class we don't want to f**k around with…
continue;
CGRect frame = [subview frame];
BOOL isLeftmostItem = frame.origin.x <= sThresholdSelectorMargin;
if (isLeftmostItem)
{
subview.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
continue;
}
BOOL isRightmostItem = (CGRectGetMaxX(self.bounds) - CGRectGetMaxX(frame)) <= sThresholdSelectorMargin;
if (!isRightmostItem)
{
subview.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
continue;
}
subview.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
}
}
@end
InterfaceBuilder でツールバーのクラスを設定しましたが、事実として、このコードが呼び出され、前述のように iOS 5.1 ではすべて正常に動作することがわかっています。
iOS バージョン 4.2 以降をサポートする必要がありますが…</p>
私が欠けているものに関するヘルプ/ヒントは大歓迎です。