菜鸟教程小白 发表于 2022-12-12 15:24:38

ios - 如何修改 PKRevealController 滑出菜单以处理 iOS 7?


                                            <p><p>我有一个使用 <a href="https://github.com/pkluz/PKRevealController" rel="noreferrer noopener nofollow">PKRevealController</a> 的应用程序它实现了一个滑出式菜单,类似于 iOS 上流行的 Facebook 和 GMAIL 应用程序中的菜单。该应用程序是在 XCode 5 中构建的,并在 iOS 6 和 iOS 7 上运行。我需要弄清楚如何让它在这两个地方都正常工作,所以一个简单的 .XIB hack 让它在 iOS 7 中看起来不错,但让它看起来在 iOS 6 中更糟糕的是不行。</p>

<p>该代码适用于 iOS 6,其中状态栏是不透明的,顶 View 未与状态栏混合使用 alpha。</p>

<p>但是,例如,在 iOS 7 上,我在我的 .xib 文件中创建了这个 View ,这是它在 ios 6 模拟器中运行时的显示方式,此处显示的是打开滑出菜单:</p>

<p> <img src="/image/bpuRd.png" alt="enter image description here"/> </p>

<p>同样的 .xib 文件在 ios 7 上运行,当滑出菜单打开时,滑出菜单的 .xib 内容的顶部现在位于状态栏下方,正如 Apple 在其 ios 7 过渡指南中所说的那样:</p>

<p> <img src="/image/yDeVr.png" alt="enter image description here"/> </p>

<p>我需要在 PKRevealController 中修改的类可能是正在创建和呈现包含 View 的呈现 ViewController ,我认为包含的 View 称为 <code>PKRevealControllerContainerView</code>。我想我可能需要创建
像这样的某种 View 层次结构:</p>

<pre><code>   [Outermost View container
      [ some kind of blob to occupy the header area ]
      [ the client view I want to appear the way it did in iOS 6]
   ]
</code></pre>

<p>我一直在阅读,可能有更简单的方法,但我不太了解它们,例如向我的 info.plist 添加属性的方法,例如 <code>查看基于 Controller 的状态栏外观</code> = <code>是</code>。我试过了,没有达到预期的效果。</p>

<p>我该如何解决这个问题?我已阅读 <a href="https://developer.apple.com/library/ios/documentation/userexperience/conceptual/TransitionGuide/" rel="noreferrer noopener nofollow">Fine Guide</a>由 Apple 发布,它没有提供代码,只有像 <a href="https://developer.apple.com/library/ios/documentation/userexperience/conceptual/TransitionGuide/Bars.html" rel="noreferrer noopener nofollow">status bar</a> 上的这个页面这样的一般指导。 .</p>

<p>复制这个问题很容易,只需克隆 git repo <code>https://github.com/pkluz/PKRevealController</code>,构建并运行。</p>

<p>弹出 View 的代码如下所示:</p>

<pre><code>- (void)addLeftViewControllerToHierarchy
{
    if (self.leftViewController != nil &amp;&amp; !)
    {
      ;
      self.leftViewContainer.viewController = self.leftViewController;

      if (self.leftViewContainer == nil)
      {
            self.leftViewContainer = [ initForController:self.leftViewController shadow:NO];
            self.leftViewContainer.autoresizingMask = ;
      }

      self.leftViewContainer.frame = ;
      ;
      ;
    }
}
</code></pre>

<p>上面是由PKRevealController.m调用的,像这样:</p>

<pre><code>- (void)showLeftViewControllerAnimated:(BOOL)animated
                            completion:(PKDefaultCompletionHandler)completion
{
    __weak PKRevealController *weakSelf = self;

    void (^showLeftViewBlock)(BOOL finished) = ^(BOOL finished)
    {
      ;
      ;// HELLO LEFT Slide-out menu.

      ....
</code></pre>

<p>有比我的想法更好的方法吗? Apple 是否提供了一些方法来简化此操作,或者尝试在单个代码库中支持 iOS 6 和 iOS 7 是否让我做上述我正在考虑的黑客行为?</p>

<p>例如,这里是一个非常丑陋的 hack,我懒得在苹果系统状态栏下方放置任何 View ,在顶部留下一个黑条,这不好,但它表明我正在修改代码中的正确区域,至少:</p>

<pre><code>- (void)addLeftViewControllerToHierarchy
{
    CGRect   lvFrame;

    if (self.leftViewController != nil &amp;&amp; !)
    {
      ;
      self.leftViewContainer.viewController = self.leftViewController;

      if (self.leftViewContainer == nil)
      {
            self.leftViewContainer = [ initForController:self.leftViewController shadow:NO];
            self.leftViewContainer.autoresizingMask = ;
      }

      lvFrame = ;
      lvFrame.origin.y += 20; // ugly hack demo code only! don&#39;t really do it this badly!
      lvFrame.size.height -= 20;
      self.leftViewContainer.frame = lvFrame;
      ;
      ;
    }
}
</code></pre>

<p>如果我也将它添加到 <code>UIViewController+PKRevealController.m</code>,上面的 hack 就足够了:</p>

<pre><code>-(UIStatusBarStyle)preferredStatusBarStyle{
    return UIStatusBarStyleBlackOpaque;
}
</code></pre>

<p>上述代码在添加时会导致以下提示/警告:</p>

<p><code>Category 正在实现一个方法,该方法也将由其主类实现。</code></p>

<p>我将上述说明包括在内以展示我的尝试,我欢迎了解真正的专家是如何做到这一点的。</p>

<p>我自己修改后的 PKRevealController 代码副本,包括上面的 hack,以略微改进的形式,可在此处找到:<code>https://github.com/wpostma/PKRevealController</code></p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>我也一直在为 PKRevealController 苦苦挣扎。虽然我仍在寻找更好的解决方案,但我会分享我到现在为止的想法。</p>

<p>我的两个问题是:</p>

<ol>
<li>状态栏样式始终相同,我希望前 View 和菜单的样式不同;</li>
<li>菜单 View 顶部单元格(它是一个表格 ViewController )显示在状态栏后面。</li>
</ol>

<h2>1。动态状态栏样式</h2>

<p>首先我有我自己的 PKRevealController 子类,我有一个自定义初始化程序和一些自定义方法来将新 ViewController 加载到前 View 导航 ViewController 中。但这暂时无关紧要。</p>

<p>我使用这个子类来实现 <code>preferredStatusBarStyle</code> 如下,以便显示 Controller 可以为每个状态提供正确的样式:</p>

<pre><code>- (UIStatusBarStyle)preferredStatusBarStyle {
    switch (self.state) {
      case PKRevealControllerFocusesLeftViewController:
            return ;
            break;
      case PKRevealControllerFocusesRightViewController:
            return ;
            break;
      case PKRevealControllerFocusesFrontViewController:
            return ;
            break;
      case PKRevealControllerFocusesLeftViewControllerInPresentationMode:
            return ;
            break;
      case PKRevealControllerFocusesRightViewControllerInPresentationMode:
            return ;
            break;

      default:
            return UIStatusBarStyleDefault;
            break;
    }
}
</code></pre>

<p>但是,仅此一项是行不通的。还是要说状态栏样式需要用<code>setNeedsStatusBarAppearanceUpdate</code>来改变。正如 Apple 所说,这应该从动画循环内部调用,您可以在 PKRevealController 的 <code>setFrontViewFrameLinearly</code> 方法中找到一个。这是我修改后的样子:</p>

<pre><code>- (void)setFrontViewFrameLinearly:(CGRect)frame
                         animated:(BOOL)animated
                         duration:(CGFloat)duration
                        options:(UIViewAnimationOptions)options
                     completion:(PKDefaultCompletionHandler)completion
{
    [UIView animateWithDuration:duration delay:0.0f options:options animations:^
    {
      self.frontViewContainer.frame = frame;
      if ([[ systemVersion] compare:@&#34;7.0&#34; options:NSNumericSearch] != NSOrderedAscending) {
            ;
      }
    }
    completion:^(BOOL finished)
    {
      safelyExecuteCompletionBlockOnMainThread(completion, finished);
    }];
}
</code></pre>

<p>如果你在这一点上尝试一下,样式将会混淆。您可以很快得出结论,当 <code>preferredStatusBarStyle</code> 被调用时,显示 Controller 状态仍然没有改变。为此,请转到设置状态的每个方法,例如<code>enterPresentationModeForRightViewControllerAnimated</code> 并在它调用对帧的任何更改之前设置状态(将触发动画循环)。我在 5 个不同的地方做过。</p>

<h2>2。带插图的左/右菜单</h2>

<p>对于这个我不得不说我使用了一种解决方法:我刚刚在表格 View 上设置了一个标题 View (<code>tableHeaderView</code> 属性)。</p>

<p>把它放在你的 UITableViewController 的 <code>viewDidLoad</code> 中:</p>

<pre><code>UIView *headerView = [ initWithFrame:CGRectMake(0.f, 0.f, self.tableView.frame.size.width, 20.f)];
headerView.backgroundColor = ;

self.tableView.tableHeaderView = headerView;
</code></pre>

<p>不要忘记添加一些条件,这样它就不会在 iOS 6 中执行。使用 <a href="https://stackoverflow.com/questions/12561599/how-to-check-ios-version-is-ios-6/12561703#12561703" rel="noreferrer noopener nofollow">this other answer</a>知道该怎么做。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 如何修改 PKRevealController 滑出菜单以处理 iOS 7?,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/19228603/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/19228603/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 如何修改 PKRevealController 滑出菜单以处理 iOS 7?