web-dev-qa-db-ja.com

透明なコンテンツを含むiOS 7ビューが前のビューと重なっています

最近、iOS 7で動作するようにxcodeプロジェクトを更新しましたが、大きな問題に直面しました。私のアプリケーション全体には背景画像が1つしかなく(キーウィンドウにUIImageViewが追加されている)、すべてのビューが透明であるため、プッシュされたView Controllerが前のビューと重なるため、UIViewControllerをプッシュするときに問題に直面します(写真で見ることができます: http://grab.by/qp0k )。これは、iOS 7でプッシュ遷移が変更されたためであると予測できます。これは、画面の半分がスライドするためです。たぶん誰もがこの問題を修正する方法を知っていますか?

これがキーウィンドウの設定方法です

  self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
 UIImageView *background = [[UIImageView alloc]initWithFrame:[[UIScreen mainScreen] bounds]];
 background.image = [UIImage imageNamed:@"background.png"]; 
UINavigationController *navi = [[UINavigationController alloc]initWithRootViewController:self.viewController];
self.window.rootViewContro‌​ller = navi;
 [self.window makeKeyAndVisible];

その後、ユーザーが「トレーニングを開始」ボタンをクリックすると、いつものように次のビューがプッシュされます。

workoutView *w = [[workoutView alloc]initWithNibName:@"workoutView" bundle:nil];
        [self.navigationController pushViewController:w animated:YES];
34
Edvardas

新しいUINavigationControllerDelegateメソッドanimationControllerForOperationを実装することで問題を解決しました。

例えば:

- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController     *)navigationController
                              animationControllerForOperation:(UINavigationControllerOperation)operation
                                           fromViewController:(UIViewController *)fromVC
                                             toViewController:(UIViewController *)toVC
{

PushTransition* transition = [PushTransition new];
[transition setNavigationControllerOperation: operation];

return transition;
}

PushTransitionは、UIViewControllerAnimatedTransitioningプロトコルと、そのプロトコルからのtransitionDurationおよびanimateTransitionの2つのメソッドを実装するクラスです。さらに、操作を渡すためのプロパティを追加しました(プッシュ遷移またはポップ遷移の場合に通知されます)。

次のように、ビューをanimateTransitionに移動するためのアニメーションコードを配置するだけです。

// the containerView is the superview during the animation process.
UIView *container = transitionContext.containerView;

UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

UIView *fromView = fromVC.view;
UIView *toView = toVC.view;
CGFloat containerWidth = container.frame.size.width;

// Set the needed frames to animate.

CGRect toInitialFrame = [container frame];
CGRect fromDestinationFrame = fromView.frame;

if ([self navigationControllerOperation] == UINavigationControllerOperationPush)
{
    toInitialFrame.Origin.x = containerWidth;
    toView.frame = toInitialFrame;
    fromDestinationFrame.Origin.x = -containerWidth;
}
else if ([self navigationControllerOperation] == UINavigationControllerOperationPop)
{
    toInitialFrame.Origin.x = -containerWidth;
    toView.frame = toInitialFrame;
    fromDestinationFrame.Origin.x = containerWidth;
}

// Create a screenshot of the toView.
UIView *move = [toView snapshotViewAfterScreenUpdates:YES];
move.frame = toView.frame;
[container addSubview:move];

[UIView animateWithDuration:TRANSITION_DURATION delay:0
     usingSpringWithDamping:1000 initialSpringVelocity:1
                    options:0 animations:^{
                        move.frame = container.frame;
                        fromView.frame = fromDestinationFrame;
                    }
                 completion:^(BOOL finished) {
                     if (![[container subviews] containsObject:toView])
                     {
                         [container addSubview:toView];
                     }

                     toView.frame = container.frame;
                     [fromView removeFromSuperview];
                     [move removeFromSuperview];
                     [transitionContext completeTransition: YES];
                 }];

それを説明し、あなたは完了できます。さらに、任意のプッシュまたはポップアニメーションを作成できます。

15
snoersnoer

これは私がしました。

-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [self.view setAlpha:0];
}

戻ってきたときにアルファを再設定することを忘れないでください。

- (void) viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [self.view setAlpha:1];
}
19
Alexandre

ビューを初期化するときにこれを行うことで修正しました:

self.view.clipsToBounds = YES;
6
Enrico Susatyo

独自のカスタムUIViewController遷移を定義できるiOS7の新しい機能を検討することをお勧めします。 UIViewControllerTransitioningDelegateのドキュメントをご覧ください。また、それについての記事へのリンクは次のとおりです。 http://www.doubleencore.com/2013/09/ios-7-custom-transitions/

4
John Jacecko

同じ問題がありました。 initメソッドで背景画像をロードしてみてください。私にとっては、(時々)うまくいきました:例えば:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
        self.view.backgroundColor = [UIColor whiteColor];
        [self.imageBack setImage:[UIImage imageNamed:@"mayBack.png"]];
    }
    return self;
}

しかし、垣間見ることができます。新しいiOS7移行プロトコルの実装に加えて、私が見つけた最良の解決策は、カテゴリを実装し、必要に応じてそのカテゴリを使用することです。あなたは答えを見つけることができます こちら

1
giuseppe

ああ、今私は問題を理解しています。あなたは正しかったのですが、以前のUIViewControllerが移行後に非表示になっていないことが原因のようです(新しい移行効果のため)。

この動作を制御するSDKメソッドはないようです。背景を静的にする必要がないようにアプリを再設計する以外に、おそらく独自のナビゲーションをロールする必要があります。 OSNavigationController は、UINavigationControllerの完全な再実装であり、役に立つかもしれません。 iOS 7への移行に合わせて更新していない場合は、おそらく大丈夫でしょう。それらがあれば、いつでも古いバージョンを使用できます。

1
Kevin

画像を背景色に設定すると、問題が解決しました。

self.view.backgroundColor = 
            [UIColor colorWithPatternImage:[UIImage imageNamed:@"mainback.png"]];
1
user3010978

@snoersnoerの小道具。


Swift 3。

func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {

    let pushTransition = SUPushTransition()
    pushTransition.navigationControllerOperation = operation
    return pushTransition
}

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {

    // the containerView is the superview during the animation process.
    let container = transitionContext.containerView

    let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)
    let toVC = transitionContext.viewController(forKey:UITransitionContextViewControllerKey.to);

    if let from = fromVC,
        let fromView = from.view,
        let to = toVC,
        let toView = to.view {

        let containerWidth = container.frame.size.width

        // Set the needed frames to animate.

        var toInitialFrame = container.frame
        var fromDestinationFrame = fromView.frame

        if self.navigationControllerOperation == .Push {
            toInitialFrame.Origin.x = containerWidth;
            toView.frame = toInitialFrame;
            fromDestinationFrame.Origin.x = -containerWidth;
        }
        else if self.navigationControllerOperation == .pop {
            toInitialFrame.Origin.x = -containerWidth;
            toView.frame = toInitialFrame;
            fromDestinationFrame.Origin.x = containerWidth;
        }

        // Create a screenshot of the toView.
        if let move = toView.snapshotView(afterScreenUpdates: true) {

            move.frame = toView.frame
            container.addSubview(move)

            UIView.animate(withDuration: Constants.MainPage.navControllerDuration, delay: 0.0, usingSpringWithDamping: 1000, initialSpringVelocity: 1, options: .curveEaseInOut, animations: {
                move.frame = container.frame;
                fromView.frame = fromDestinationFrame;
            }, completion: { (finished) in

                if finished {

                    if !container.subviews.contains(toView) {
                        container.addSubview(toView)
                    }

                    toView.frame = container.frame

                    fromView.removeFromSuperview()
                    move.removeFromSuperview()

                    transitionContext.completeTransition(true)
                }

            })

        }

    }

}

乾杯。

0
Brandon A

その投稿のUINavigationControllerカテゴリを見てください(問題を解決しました):

https://stackoverflow.com/a/18882232/2826409

0
Eran Katsav