Каков наилучший способ разработки меню для бокала, как в новом приложении для iOS для Facebook?

Похоже, что меню боковой перетаскивания становится более распространенным элементом интерфейса, так как больше информации загружается в каждое приложение для iPhone. Facebook включил его в свою последнюю версию и новое приложение Gmail также включило его. Мне было интересно, есть ли у кого-нибудь мысли о наиболее эффективном способе разработки чего-то подобного, поскольку он становится более распространенным элементом интерфейса. Хотя у меня есть свои мысли о том, как это сделать, мне любопытно узнать, что думают другие люди.

Facebook swipe navigation

Ответ 1

Недавно я столкнулся с этим, на самом деле не смотрел на код или не тестировал элемент управления, но похоже, что это может быть очень достойная отправная точка.

jtrevealsidebar

Изменить: Читатель должен также взглянуть на другие ответы:)

Ответ 2

Для Тома Адриаенсена отличная библиотека: Inferis/ViewDeck

Он очень прост в использовании и имеет довольно большое значение.

EDIT:

Для чего-то немного более легкого, проверьте: mutualmobile/MMDrawerController

Он не имеет всех функций ViewDeck, но его проще модифицировать и расширять.

Ответ 3

Я создал для этого библиотеку. Он называется MFSideMenu.

Помимо всего прочего, он включает поддержку iphone + ipad, портрет + пейзаж, меню слева или справа, UITabBarController и жесты панорамы.

Ответ 4

Проверьте MMDrawerController:

MMDrawerController

Мы не смогли найти библиотеку, которая нам понравилась, поэтому мы просто перевернули ее.

Ответ 5

ключевая идея, которую вы должны установить self.navigationController.view или центр. Существует два события, с которыми вам приходится обращаться. (1) barButtonItem нажмите. (2) жест передвижения из-за прокрутки.

Вы можете отправить контроллер просмотра на задний план следующим образом:

[self.view sendSubviewToBack:menuViewController.view];

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(buttonPressed:)];
    UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
    [self.navigationController.view addGestureRecognizer:panGestureRecognizer];
    self.navigationItem.leftBarButtonItem = barButtonItem;
}

- (void)buttonPressed:(id)sender {

    CGRect destination = self.navigationController.view.frame;

    if (destination.origin.x > 0) {
        destination.origin.x = 0;
    } else {
        destination.origin.x = 320;
    }

    [UIView animateWithDuration:0.25 animations:^{
        self.navigationController.view.frame = destination;
    }];
}

- (void)handlePan:(UIPanGestureRecognizer *)recognizer
{
    static CGPoint originalCenter;

    if (recognizer.state == UIGestureRecognizerStateBegan)
    {
        originalCenter = recognizer.view.center;

    } else if (recognizer.state == UIGestureRecognizerStateChanged)
    {
        CGPoint translation = [recognizer translationInView:self.view];

        recognizer.view.center = CGPointMake(originalCenter.x + translation.x, originalCenter.y);
    }
    else if (recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateCancelled || recognizer.state == UIGestureRecognizerStateFailed)
    {
        if (recognizer.view.frame.origin.x < 160) {
            [UIView animateWithDuration:0.25 animations:^{
                recognizer.view.center = CGPointMake(384, 487.5);
            }];
        } else {
            [UIView animateWithDuration:0.25 animations:^{
                recognizer.view.center = CGPointMake(384 + 320, 487.5);
            }];
        }
    }
}

Ответ 6

Реализация Facebook помещает UIPanGestureRecognizer в UINavigationBar. Таким образом, позволяя ловить удары там, где это необходимо.

Это позволяет делать такие вещи, как непосредственное распознавание направления касания в x/z, а также скорость, с которой они имели место.

Кроме того, такой вид перехвата UIViews (более одного на экране одновременно с явно разными задачами → таким образом разные контроллеры) должен (я хочу сказать, должен) использовать iOS новые функции ViewController-Containment. Каждая реализация без этого просто плоха, поскольку она возится с иерархией представлений способом, не предназначенным Apple.

На стороне: Если вам действительно интересно узнать, как это можно сделать как можно ближе к способу Facebook, ознакомьтесь с проектом, который я открываю из Github PKRevealController.

Ответ 7

Еще лучше JASidePanels. Легко реализуется и работает как для iPhone, так и для iPad.

Ссылка Github: JASidePanels

Ответ 8

Существуют десятки разных библиотек, созданных разработчиками для реализации навигации по стилю Facebook/Path для приложений iOS. Я могу перечислить все из них, но, поскольку вы попросили лучшего, вот мои два варианта, которые я использую для реализации навигационного меню боковой навигации:

1) ECSlidingViewController Его очень легко реализовать и использовать Раскадровки. У меня не было никаких проблем с его внедрением и не было никаких ошибок или что-то в этом роде. Ссылка, которую я предоставил, содержит почти все объяснения, чтобы использовать ее.

2) SWRevealViewController Эта библиотека проста в использовании, и вы можете найти учебник ЗДЕСЬ, который показывает, как реализовать его со всем объяснением вместе с изображениями. Вы можете просто следовать инструкциям и поблагодарить меня позже.

Ответ 9

Другой вариант - использовать Scringo. Это дает вам боковое меню, например, в приложениях youtube/facebook, а также всевозможные встроенные функции в меню, которое вы можете добавить (например, чат, приглашать друзей и т.д.).

Добавление бокового меню - это просто вызов [ScringoAgent startSession...], и вся конфигурация может быть выполнена на сайте.

Ответ 11

Этот вопрос довольно популярен, но все сводится к простому импорту и использованию для меня... Вот что я использую... SWRevealController.

Я удивлен, что люди скучают по нему... Это действительно БОЛЬШОЕ!!! и проста в использовании. Разработчик даже включает несколько примеров проектов, которые позволяют вам увидеть, как использовать его в разных сценариях.

Ответ 13

Как Gmail, так и Facebook сильно используют веб-представления, поэтому трудно сказать, какой именно код и какой визуализированный HTML. Однако, глядя на интерфейс, похоже, что они разместили UITableView с шириной, более узкой, чем ширина экрана (320pt) под UIView, которая содержит контент, который они хотят отобразить. Выбор различных строк таблицы таблиц, вероятно, свопит подзаголовок представления содержимого.

По крайней мере, как я подхожу к проблеме. Трудно диктовать, что это должно быть. Просто прыгайте прямо и начинайте экспериментировать!

Ответ 14

вид справа может находиться внутри подкласса UIScrollView. В этом подклассе вы можете переопределить - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event, чтобы вернуть YES, только если пользователь коснулся подвью. Таким образом, вы можете разместить свой прозрачный UIScrollView над любым другим представлением и пройти через любое событие касания, которое происходит вне subview; и вы бесплатно получаете материалы прокрутки.

Например:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
    CGPoint location=[self convertPoint:point toView:subview];
    return (location.x > 0 && 
            location.x < subview.frame.size.width && 
            location.y > 0 && 
            location.y < subview.frame.size.height);
}

или

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
    return [subview pointInside:
             [self convertPoint:point toView:subview] withEvent:event];

Ответ 15

Попробуйте добавить свое меню (которое вы проведите по экрану) под основным видом. Начните подписку на события касания в представлении.

Внедрите touchesMoved: и проверьте, является ли первая gesture вертикальной (прокрутите главное представление, если необходимо) или горизонтально (здесь вы хотите отобразить меню). Если он горизонтальный, начните вызывать другой метод, - (void)scrollAwayMainView:(NSUInteger)pixels, всякий раз, когда touchesMoved: вызывается, вычисляя количество пикселей от начальной точки, основной вид должен быть, и передавая это число в метод. В реализации этих методов выполните следующий код:

[mainView scrollRectToVisible:CGRectMake:(pixels, 
                                          mainView.origin.y, 
                                          mainView.size.width, 
                                          mainView.size.height];

Ответ 16

Если вы хотите, я сделал это репо на github GSSlideMenu Это позволяет вам создавать меню в стиле Facebook, но с "back" webView (как правило, все найденные мной репозитории имеют представление tableView как "назад" ).

Ответ 17

это точно клон боковой панели facebook: Библиотека GHSidebarNav

очень проста в использовании. инструкции находятся в

Ответ 18

Посмотрите мое решение по этому вопросу:

Как создать пользовательское меню слайдов без сторонней библиотеки.?

Один класс, который вам нужен только для подкласса и заполнения содержимого.

Вот класс. Для получения дополнительной информации см. Приведенную выше ссылку.

#import <UIKit/UIKit.h>

@interface IS_SlideMenu_View : UIView <UIGestureRecognizerDelegate>
{
    UIView* transparentBgView;
    BOOL hidden;
    int lastOrientation;
}

@property (strong, nonatomic) UIView *menuContainerV;

+ (id)sharedInstance;

- (BOOL)isShown;
- (void)hideSlideMenu;
- (void)showSlideMenu;

@end


#import "IS_SlideMenu_View.h"

@implementation IS_SlideMenu_View

+ (id)sharedInstance
{
    static id _sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[[self class] alloc] init];
    });

    return _sharedInstance;
}

- (instancetype)initWithFrame:(CGRect)frame
{
    frame = [[[UIApplication sharedApplication] delegate] window].frame;
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor clearColor];

        transparentBgView = [[UIView alloc] initWithFrame:frame];
        [transparentBgView setBackgroundColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:0.6]];
        [transparentBgView setAlpha:0];
        transparentBgView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(gestureRecognized:)];
        UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(gestureRecognized:)];
        [transparentBgView addGestureRecognizer:tap];
        [transparentBgView addGestureRecognizer:pan];

        [self addSubview:transparentBgView];

        frame.size.width = 280;
        self.menuContainerV = [[UIView alloc] initWithFrame:frame];
        CALayer *l = self.menuContainerV.layer;
        l.shadowColor = [UIColor blackColor].CGColor;
        l.shadowOffset = CGSizeMake(10, 0);
        l.shadowOpacity = 1;
        l.masksToBounds = NO;
        l.shadowRadius = 10;
        self.menuContainerV.autoresizingMask = UIViewAutoresizingFlexibleHeight;

        [self addSubview: self.menuContainerV];
        hidden = YES;
    }

    //----- SETUP DEVICE ORIENTATION CHANGE NOTIFICATION -----
    UIDevice *device = [UIDevice currentDevice];
    [device beginGeneratingDeviceOrientationNotifications];
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
    [nc addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:device];

    lastOrientation = [[UIDevice currentDevice] orientation];

    return self;
}

//********** ORIENTATION CHANGED **********
- (void)orientationChanged:(NSNotification *)note
{
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];    
    if(orientation == UIDeviceOrientationPortrait || orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight){
        NSLog(@"%ld",orientation);
        if(!hidden && lastOrientation != orientation){
            [self hideSlideMenu];
            hidden = YES;
            lastOrientation = orientation;
        }
    }
}

- (void)showSlideMenu {
    UIWindow* window = [[[UIApplication sharedApplication] delegate] window];
    self.frame = CGRectMake(0, 0, window.frame.size.width, window.frame.size.height);

    [self.menuContainerV setTransform:CGAffineTransformMakeTranslation(-window.frame.size.width, 0)];

    [window addSubview:self];
//    [[UIApplication sharedApplication] setStatusBarHidden:YES];

    [UIView animateWithDuration:0.5 animations:^{
        [self.menuContainerV setTransform:CGAffineTransformIdentity];
        [transparentBgView setAlpha:1];
    } completion:^(BOOL finished) {
        NSLog(@"Show complete!");
        hidden = NO;
    }];
}

- (void)gestureRecognized:(UIGestureRecognizer *)recognizer
{
    if ([recognizer isKindOfClass:[UITapGestureRecognizer class]]) {
        [self hideSlideMenu];
    } else if ([recognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
        static CGFloat startX;
        if (recognizer.state == UIGestureRecognizerStateBegan) {
            startX = [recognizer locationInView:self.window].x;
        } else
        if (recognizer.state == UIGestureRecognizerStateChanged) {
            CGFloat touchLocX = [recognizer locationInView:self.window].x;
            if (touchLocX < startX) {
                [self.menuContainerV setTransform:CGAffineTransformMakeTranslation(touchLocX - startX, 0)];
            }
        } else
        if (recognizer.state == UIGestureRecognizerStateEnded) {
            [self hideSlideMenu];
        }
    }
}

- (void)hideSlideMenu
{
    UIWindow* window = [[[UIApplication sharedApplication] delegate] window];
    window.backgroundColor = [UIColor clearColor];
    [UIView animateWithDuration:0.5 animations:^{
        [self.menuContainerV setTransform:CGAffineTransformMakeTranslation(-self.window.frame.size.width, 0)];
        [transparentBgView setAlpha:0];
    } completion:^(BOOL finished) {
        [self removeFromSuperview];
        [self.menuContainerV setTransform:CGAffineTransformIdentity];

//        [[UIApplication sharedApplication] setStatusBarHidden:NO];
        hidden = YES;
        NSLog(@"Hide complete!");
    }];
}

- (BOOL)isShown
{
    return !hidden;
}

@end