Jaki jest najlepszy sposób na stworzenie menu sideswipe jak ten w nowej aplikacji Facebook iOS?

Wygląda na to, że menu side-swipe staje się bardziej powszechnym elementem interfejsu, ponieważ więcej informacji zostaje zapchanych do każdej aplikacji na iPhone ' a. Facebook włączył go do swojej najnowszej wersji i nowa aplikacja Gmail wydaje się również zawierać go . Zastanawiałem się, czy ktoś ma przemyślenia na temat najskuteczniejszego sposobu rozwijania czegoś takiego, ponieważ staje się to bardziej powszechnym elementem interfejsu. Chociaż mam własne przemyślenia na temat tego, jak to zbudować, jestem ciekaw co myślą inni.

Nawigacja Facebook swipe

Author: BoltClock, 2011-11-03

18 answers

Ostatnio natknąłem się na to, właściwie nie spojrzałem na kod ani nie przetestowałem kontroli, ale wygląda na to, że może to być bardzo przyzwoity punkt wyjścia.

Jtrevealsidebar

Edytuj: Czytelnik powinien również przyjrzeć się innym odpowiedziom:)

 34
Author: Zaky German,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-21 10:55:34

Istnieje wielka biblioteka do tego Tom Adriaenssen: Inferis / ViewDeck

Jest bardzo łatwy w użyciu i ma dość duży following.

EDIT:

Aby uzyskać coś bardziej lekkiego, sprawdź: mutualmobile / MMDrawerController

Nie posiada wszystkich funkcji ViewDeck, ale jest prostszy do modyfikacji i rozszerzenia.

 84
Author: Chris Knadler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-16 07:24:20

Stworzyłem do tego bibliotekę. Nazywa się MFSideMenu.

Zawiera między innymi wsparcie dla iphone+ipad, portret + krajobraz, menu po lewej lub prawej stronie, UITabBarController i gestów pan.

 48
Author: Michael Frederick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-25 19:19:33

Sprawdź MMDrawerController:

MMDrawerController

Nie mogliśmy znaleźć biblioteki, która nam się spodobała, więc zwijaliśmy własną.

 29
Author: kcharwood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-20 06:47:38

Kluczowa idea , że musisz ustawić siebie.navigationController.ramka lub środek widoku . Istnieją dwa zdarzenia, które musisz obsłużyć. (1) (2) gest pan z powodu przesuwania.

Możesz wysłać kontroler widoku do tła w następujący sposób:

[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);
            }];
        }
    }
}
 12
Author: János,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-12 20:33:22

Jeszcze lepiej jest JASidePanels . Łatwo zaimplementowany i działa zarówno na iPhone ' a, jak i iPada.

Github link: JASidePanels

 11
Author: user2330922,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-20 06:49:20

Implementacja Facebook ' a umieszcza UIPanGestureRecognizer na pasku UINavigationBar. Pozwalając w ten sposób łapać szarpnięcia tam, gdzie jest to potrzebne.

Który pozwala na takie rzeczy jak, rozpoznawanie kierunku dotyku w x / Z bezpośrednio, jak również prędkość, z którą wystąpiły.

Również tego typu Majsterkowanie z UIViews (więcej niż jeden na ekranie na raz z ewidentnie różnymi zadaniami - > a więc różnymi kontrolerami) powinno (pokuszę się powiedzieć, że musi) używać iOS new ViewController-zabezpieczenie funkcje. Każda implementacja bez tego jest po prostu zła, ponieważ majstruje w hierarchii widoków w sposób nie zamierzony przez Apple.

Na marginesie: jeśli jesteś naprawdę ciekawy, jak można to zrobić tak blisko Facebook sposób, jak to możliwe, sprawdź projekt, który otworzyłem na GithubPKRevealController .

 11
Author: pkluz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-20 06:50:09

Istnieją dziesiątki różnych bibliotek, które programiści stworzyli do implementacji nawigacji w stylu Facebook / Path dla aplikacji iOS. Mogę wymienić wszystkie z nich, ale jak poprosiłeś o najlepszy, oto moje dwie opcje, których używam do implementacji menu nawigacji Side swipe:

1) ECSlidingViewController Jego bardzo łatwe do wdrożenia i użycia storyboardy również. Nie miałem żadnych problemów z jego implementacją, ani nie otrzymałem żadnych błędów ani niczego podobnego. Link który podałem ma ładny Wiele wszystkich wyjaśnień, aby go użyć.

2) SWRevealViewController Ta Biblioteka jest łatwa w użyciu i możesz znaleźć tutorial tutaj , który pokazuje, jak ją zaimplementować wraz z całym wyjaśnieniem wraz z obrazami. Możesz po prostu postępować zgodnie z samouczkiem i podziękować mi później.

 8
Author: AJ112,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-12 21:26:22

Inną opcją jest użycie Scringo . Daje menu boczne, jak w aplikacjach youtube/facebook, a także wszelkiego rodzaju wbudowane funkcje w menu, które można dodać (np...)

Dodanie bocznego menu jest po prostu wywołaniem [scringoagent startSession...] i całą konfigurację można wykonać na stronie.

 7
Author: hungary54,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-18 07:20:19

Zobacz tutaj, bardzo dobry punkt wyjścia: Przesuń nawigację jak facebook i ścieżka

 4
Author: ZTAN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-20 06:46:57

To pytanie jest dość popularne, ale wszystko sprowadza się do łatwego importowania i używania dla mnie... Oto, czego używam... SWRevealController .

Dziwi mnie, że ludzie za tym tęsknią... To naprawdę jest świetne!!! i łatwy w użyciu. Deweloper zawiera nawet kilka przykładowych projektów, które pozwalają zobaczyć, jak go używać w różnych scenariuszach.
 4
Author: jsetting32,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-23 16:41:16
 3
Author: Victor Sigler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-12 16:28:04

Zarówno Gmail, jak i Facebook intensywnie korzystają z widoków stron internetowych, więc trudno powiedzieć, co to jest rodzimy kod, a co renderowany HTML. Jednak patrząc na interfejs, wygląda na to, że umieścili UITableView o szerokości węższej niż szerokość ekranu (320pt) pod UIView, który zawiera zawartość, którą chcą wyświetlić. Wybranie różnych wierszy tableview prawdopodobnie zamienia widok podrzędny widoku zawartości.

Przynajmniej tak podchodziłbym do problemu. Trudno dyktować co to powinno być. Po prostu wskocz i zacznij eksperymentować!

 2
Author: Ash Furrow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-03 02:47:47

If you want I did this repo on github GSSlideMenu To pozwala na tworzenie menu w stylu Facebook, ale z" wstecz " webView (ogólnie wszystkie repos, które znalazłem ma widok tableView jako "wstecz" widok).

 1
Author: JAA,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-20 06:49:45

To jest dokładnie klon facebook sidebar : Biblioteka GHSidebarNav

Bardzo łatwy w użyciu. instrukcja jest w

 1
Author: Max_Power89,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-12 21:31:55

Widok po prawej stronie może znajdować się wewnątrz podklasy UIScrollView. W tej podklasie możesz nadpisać - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event, aby zwrócić Yes tylko wtedy, gdy użytkownik dotknął subview. W ten sposób możesz umieścić przezroczysty Widok UIScrollView na dowolnym innym widoku i przejść przez każde zdarzenie dotykowe, które odbywa się poza subview; a otrzymasz przewijanie rzeczy za darmo.

Na przykład:

- (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);
}

Lub:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
    return [subview pointInside:
             [self convertPoint:point toView:subview] withEvent:event];
 1
Author: javieralog,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-07 13:11:09

Spróbuj dodać menu (które przesuń palcem, aby dostać się do) pod głównym widokiem. Rozpocznij subskrypcję wydarzeń Dotknij w widoku.

Zaimplementuj touchesMoved: i sprawdź, czy pierwsza gesture jest pionowa (przewiń główny widok w razie potrzeby) lub pozioma(tutaj chcesz pokazać menu). Jeśli jest pozioma, zacznij wywoływać inną metodę, - (void)scrollAwayMainView:(NSUInteger)pixels, ilekroć zostanie wywołana touchesMoved:, oblicz liczbę pikseli oddalonych od punktu początkowego głównego widoku i przekaż tę liczbę do metoda. W implementacji tej metody uruchom następujący kod:

[mainView scrollRectToVisible:CGRectMake:(pixels, 
                                          mainView.origin.y, 
                                          mainView.size.width, 
                                          mainView.size.height];
 1
Author: aopsfan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-07 13:11:58

Zobacz moje rozwiązanie na to pytanie:

Jak utworzyć niestandardowe menu slajdów bez biblioteki stron trzecich.?

Jedna klasa, którą musisz tylko podklasować i wypełnić treścią.

Oto Klasa. Aby uzyskać więcej informacji, zobacz powyższy link.

#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
 0
Author: David Tarnok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:21