iOS 上滑菜单

Posted

技术标签:

【中文标题】iOS 上滑菜单【英文标题】:iOS Slide up menu 【发布时间】:2012-10-09 05:10:54 【问题描述】:

我正在尝试创建一个类似于 iPhone 目标应用程序的菜单系统。菜单如下所示:

(来源:iclarified.com)

我一直在互联网上搜索,并没有找到很多信息。据我所知,我必须创建一个 UIView 作为菜单,偏移视图并检测何时触摸它以向上滑动。菜单视图中的这些按钮必须像标签栏控制器一样加载其他视图,同时保持菜单标签在底部向上滑动。向上滑动菜单,点击您想去的地方的按钮,在向下滑动按钮的同时加载该视图。

动画看起来很简单,它使它像标签栏控制器一样工作并且始终保持在视图中,以及如何检测菜单的滑动(可能与 UIScrollView 相关)?

任何帮助都会很棒,不知道从哪里开始。

【问题讨论】:

【参考方案1】:

最多 5 步包含子视图本身的创建,但如果您只对从第 5 步读取的拖动事件感兴趣,那就是 panGestureRecognizer。

    创建自定义 UIView,我还创建了一个委托协议,用于在子视图上发生操作时通知 viewController。根据您的子视图的复杂程度,您可能需要为此创建一个具有相同名称的 xib 文件。以后我们就叫它filterView吧。

    在filterView上创建“hide”和“show”两个方法。如果你不想有一个按钮(即带箭头的小按钮,我称之为dropdownButton)来关闭和打开filterView,你可以跳过这一步,但我强烈建议实现它们。您要做的就是将 filterView.frame.origin.y 动画化为

    [[UIScreen mainScreen] bounds].size.height - dropDownButton.frame.height 隐藏filterView

    [[UIScreen mainScreen] bounds].size.height - filterView.frame.size.height 显示它。

如果需要,我还可以发送该动画的代码。

3。 打开 UIViewController 的 xib 文件并添加一个 UIView,以便只有它的下拉按钮可见。单击视图并使用界面构建器中最右侧的窗格将其类更改为 filterView。在此步骤中,如果您正确执行所有操作,您应该能够在页面底部看到您的 filtersView 的提示。如果不是,filterView.xib 文件可能没有正确连接到 filterView 源代码文件。

4 . 在 ViewController 中导入 FilterView 并作为 IBOutlet 连接并合成它。如果您编写了委托协议,请实施委托协议。如果您在 filterView 上有按钮,稍后您将需要它。委托协议应包括可选消息,如

-(void) featuresButtonTappedOnFilterView: (FilterView *) filterView;

在实现中你应该做你必须在 viewController 中做的事情,比如打开另一个 viewController。

5 .在 viewControllers xib 文件上创建一个 panGestureRecognizer 并将其添加到您的 filterView。 PanGestureRecognizer 是一个手势识别器,它将处理拖动事件。一开始,整个 filterView 可以通过点击它上面的任意点来拖动,我们稍后会谈到。将 gestureRecognizer 连接为 IBOutlet 并创建一个 IBAction(最好使用更好的名称),例如:

-(IBAction)_panRecogPanned:(id)sender;

在 ViewController 的 viewDidLoad 方法中不要忘记将委托设置为:

[_panRecog setDelegate:self];

6 .实施其他状态以获得更多权力。但 stateChanged 一开始就足够了。

- (IBAction)_panRecogPanned:(id)sender 

    switch ([(UIPanGestureRecognizer*)sender state]) 


    case UIGestureRecognizerStateBegan:   break;
    case UIGestureRecognizerStateChanged: 

       if ( [((UIPanGestureRecognizer *)sender) locationInView:_filterView].y > dropDownButton.frame.height ) 
            return; // Only drag if the user's finger is on the button

        CGPoint translation = [_panRecog translationInView:filterView];

      //Note that we are omitting translation.x, otherwise the filterView will be able to move horizontally as well. Also note that that MIN and MAX were written for a subview which slides down from the top, they wont work on your subview.
        CGRect newFrame = _panRecog.view.frame;
        //newFrame.origin.y = MIN (_panRecog.view.frame.origin.y + translation.y, FILTER_OPEN_ORIGIN_Y);
        //newFrame.origin.y = MAX (newFrame.origin.y, FILTER_INITIAL_ORIGIN_Y);
        newFrame.origin.y = _panRecog.view.frame.origin.y + translation.y;
        _panRecog.view.frame = newFrame;

        [_panRecog setTranslation:CGPointMake(0, 0) inView:self.view];


     break;

    //Remember the optional step number 2? We will use hide/ show methods now:
    case UIGestureRecognizerStateEnded:
    case UIGestureRecognizerStateCancelled: 

    //CGPoint velocity = [_panRecog velocityInView:_panRecog.view];
    //Bonus points for using velocity when deciding what to do when if the user lifts his finger

        BOOL open;

        /*
        if (velocity.y < -600.0) 
            open = NO;
        

        else if (velocity.y >= 600.0) 
            open = YES;
         else
        */

        if ( _panRecog.view.frame.origin.y > (FILTER_OPEN_ORIGIN_Y + FILTER_INITIAL_ORIGIN_Y) / 2 ) 
            open = YES;
        

        else 
            open = NO;
        


        if (open == YES)  

            [_filterView show];
        

        else       
            [_filterView hide];

        

     break;

    default:
        break;

注意:我的过滤器视图位于页面顶部而不是底部,因为它是子视图将移出页面边框。注释掉 MAX 和 MIN 语句来解决这个问题,我懒得自己写了。代码在复制粘贴后被修改,它可能(并且可能会)包含拼写错误。

【讨论】:

这太棒了,我可以使用这种方法让它工作。我听取了您的建议并实现了按钮,非常好!非常感谢! Yunus Nedim Mehel:除了您使用 panRecognized 而他使用 ccTouches 之外,这是否与此类似? sugartin.info/2012/10/01/… 是的,我看过视频,行为非常相似。在我的版本中,y 轴上的最大位置是有限的,除了手势识别器之外,还有一些按钮可以隐藏/显示视图。 你不是漏掉了switch _panRecogPaned方法的开头吗? 确实,我已经修好了。谢谢【参考方案2】:

我认为您试图让它变得过于复杂 - 只需将视图和位置设置为大部分不在屏幕上,只显示一个提示。当您触摸提示时,将视图移动到完全可见,并将该移动置于动画块中。

菜单项可能只是在该视图上带有自定义图形的 UIButton。

【讨论】:

我同意,这听起来确实是一个更好的解决方案。唯一担心的是我不想只是点击提示,我还希望能够触摸是,按住,然后向上滑动菜单然后再向下滑动。那是我最麻烦的地方。 然后你可以使用拖动事件,例如如此处所述:***.com/questions/4707858/basic-drag-and-drop-in-ios【参考方案3】:

不要想复杂,逻辑很简单。设置它的高度和宽度,使其不在屏幕上。尝试这种方法,然后提供您的反馈。检查http://blogsbits.com 这个方法会有所帮助。 hit 和 try 方法可以用来检查这些变量。

【讨论】:

以上是关于iOS 上滑菜单的主要内容,如果未能解决你的问题,请参考以下文章

Android 自定义View绘制汉堡菜单

QT for symbian 中自定义菜单怎么实现?

安卓一键变成ios界面,界面简单又整洁

如何在 Unity Editor 中绘制自定义菜单

iOS 后台挂起的一些坑

如何在AngularJS中动画菜单打开/关闭