Facebook의 새로운 iOS 앱과 같은 사이드 와이프 메뉴를 개발하는 가장 좋은 방법은 무엇입니까?
사이드 스 와이프 메뉴가 더 많은 정보가 각 iPhone 응용 프로그램에 적용됨에 따라 더욱 일반적인 인터페이스 요소가되고있는 것으로 보입니다. Facebook은 최신 버전으로이를 포함 시켰으며 새로운 Gmail 앱에도 포함되어있는 것으로 보입니다 . 더 일반적인 인터페이스 요소가되고 있기 때문에 누군가가 이와 같은 것을 개발하는 가장 효율적인 방법에 대해 생각하고 있는지 궁금합니다. 나는 이것을 구축하는 방법에 대한 내 자신의 생각을 가지고 있지만 다른 사람들의 생각을 듣고 싶어합니다.
나는 최근에 이것을 보았고 실제로 코드를 보거나 컨트롤을 테스트하지는 않았지만 매우 괜찮은 출발점이 될 것 같습니다.
편집 : 독자는 다른 답변도 살펴 봐야합니다 :)
Tom Adriaenssen의 훌륭한 라이브러리가 있습니다 : Inferis / ViewDeck
사용하기가 매우 쉽고 다음과 같은 특징이 있습니다.
편집하다:
좀 더 가벼운 것을 원한다면 mutualmobile / MMDrawerController를 확인하십시오.
ViewDeck의 모든 기능을 갖추고 있지는 않지만 수정 및 확장이 더 간단합니다.
이를 위해 라이브러리를 만들었습니다. MFSideMenu 라고 합니다 .
아이폰 + 아이 패드, 세로 + 가로, 왼쪽 또는 오른쪽의 메뉴, UITabBarController, 팬 제스처 지원 등이 있습니다.
MMDrawerController를 확인하십시오.
우리가 좋아하는 라이브러리를 찾을 수 없었으므로 우리는 우리 자신의 것을 굴 렸습니다.
키 생각 당신은해야한다는 설정 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);
}];
}
}
}
JASidePanels 가 더 좋습니다 . iPhone과 iPad 모두에서 쉽게 구현되고 작동합니다.
Github 링크 : JASidePanels
Facebook의 구현은 UINavigationBar에 UIPanGestureRecognizer를 배치합니다. 따라서 필요한 곳에서 스 와이프를 잡을 수 있습니다.
이를 통해 x / z의 터치 방향과 발생 속도를 직접 인식하는 등의 작업을 수행 할 수 있습니다.
또한 UIViews (아마도 다른 작업-> 따라서 다른 컨트롤러로 한 번에 하나 이상의 화면에서)와 같은 종류의 땜질은 iOS의 새로운 ViewController-Containment 기능을 사용해야합니다. 그것없이 모든 구현은 단순히 애플이 의도하지 않은 방식으로 뷰 계층 구조를 고려하기 때문에 나쁘다.
참고 사항 : 가능한 한 Facebook과 가까운 방법으로 궁금한 점이 있다면 Github PKRevealController 에서 오픈 소스 프로젝트를 확인하십시오 .
iOS 앱용 Facebook / Path 스타일 탐색을 구현하기 위해 개발자가 만든 수십 개의 서로 다른 라이브러리가 있습니다. 나는 그것들을 모두 나열 할 수 있지만 가장 좋은 것을 요구 한 것처럼 측면 스 와이프 탐색 메뉴를 구현하는 데 사용하는 두 가지 선택 사항이 있습니다.
1) ECSlidingViewController 스토리 보드를 구현하고 사용하는 것도 매우 쉽습니다. 나는 그것을 구현하는 데 아무런 문제가 없었거나 오류 나 그와 비슷한 것을받지 못했습니다. 내가 제공 한 링크에는 사용하기 위해 거의 모든 설명이 있습니다.
2) SWRevealViewController 이 라이브러리는 사용하기 쉽고 이미지와 함께 모든 설명과 함께 구현하는 방법을 보여주는 자습서를 여기 에서 찾을 수 있습니다. 당신은 단지 튜토리얼을 따르고 나중에 감사 할 수 있습니다.
또 다른 옵션은 Scringo 를 사용하는 것 입니다. youtube / facebook 앱과 같은 사이드 메뉴와 추가 할 수있는 메뉴의 모든 내장 기능 (예 : 채팅, 친구 초대 등)을 제공합니다.
사이드 메뉴를 추가하면 [ScringoAgent startSession ...]을 호출하기 만하면 사이트에서 모든 구성을 수행 할 수 있습니다.
아주 좋은 시작점을 참조하십시오 : 페이스 북 및 경로와 같은 탐색을 밀어 내십시오 .
이 질문은 매우 인기가 있지만 모두 가져 오기 및 사용이 쉬워졌습니다 ... 여기 내가 사용하는 것이 있습니다 ... SWRevealController .
나는 사람들이 그것을 그리워하는 것에 놀랐다. .. 그것은 정말로 위대하다! !! 사용하기 쉽습니다. 개발자는 다른 시나리오에서 사용하는 방법을 볼 수있는 몇 가지 예제 프로젝트도 포함합니다.
Swift and Objective-C에서 자신 만의 Slide-Out-Navigation을 개발하는 방법에 대한 훌륭한 안내서.
목표 -C
빠른
Gmail과 Facebook은 모두 웹보기를 많이 사용하므로 기본 코드 및 HTML 렌더링 내용을 말하기가 어렵습니다. 그러나 인터페이스를 보면 표시하려는 내용이 포함 된 UIView 아래의 화면 너비 (320pt)보다 좁은 너비의 UITableView를 배치 한 것처럼 보입니다. 다른 테이블 뷰 행을 선택하면 내용 뷰의 하위 뷰가 교체 될 수 있습니다.
적어도 그것이 내가 문제에 접근하는 방법입니다. 그것이 무엇인지 지시하기는 어렵습니다. 바로 들어가서 실험을 시작하십시오!
내가 github GSSlideMenu 에서이 repo를 원한다면 "back"webView (일반적으로 내가 찾은 모든 repos는 tableView를 "back"보기로 사용)로 Facebook 스타일 메뉴 BUT을 만들 수 있습니다.
이것은 페이스 북 사이드 바의 복제본입니다 : GHSidebarNav library
사용하기 매우 쉽습니다. 지시는
오른쪽의 뷰는 UIScrollView의 서브 클래스 안에있을 수 있습니다. 이 서브 클래스에서 사용자가 서브 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
뷰를 터치 한 경우에만 YES를 리턴하도록 대체 할 수 있습니다 . 이 방법으로 투명 UIScrollView를 다른보기 위에 놓고 하위보기 외부에서 발생하는 모든 터치 이벤트를 전달할 수 있습니다. 그리고 당신은 무료로 스크롤 물건을 얻습니다.
예를 들면 다음과 같습니다.
- (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];
기본보기 아래에 메뉴 (스 와이프하여 스 와이프)를 추가해보십시오. 보기에서 이벤트를 터치하여 구독을 시작하십시오.
를 구현 touchesMoved:
하고 첫 번째 gesture
가 수직인지 (필요한 경우 기본보기를 스크롤) 수평인지 (여기서 메뉴를 표시 하려는지) 확인하십시오. 수평 인 경우, 호출 - (void)scrollAwayMainView:(NSUInteger)pixels
될 때마다 다른 메소드를 호출하기 시작 touchesMoved:
하고 메인 뷰에서 시작점에서 떨어진 픽셀 수를 계산 한 다음 해당 숫자를 메소드에 전달하십시오. 해당 메소드 구현에서 다음 코드를 실행하십시오.
[mainView scrollRectToVisible:CGRectMake:(pixels,
mainView.origin.y,
mainView.size.width,
mainView.size.height];
이 질문에 대한 해결책을 확인하십시오.
타사 라이브러리없이 사용자 정의 슬라이드 메뉴를 만드는 방법은 무엇입니까?
서브 클래스로만 컨텐츠를 채울 필요가있는 하나의 단일 클래스.
여기 수업이 있습니다. 자세한 내용은 위의 링크를 참조하십시오.
#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
'IT' 카테고리의 다른 글
iOS11 / Xcode 9에서 TIC 읽기 상태 1:57은 무엇입니까? (0) | 2020.06.07 |
---|---|
단위 테스트 무효 방법? (0) | 2020.06.07 |
왜 필드 셋 태그가 필요합니까? (0) | 2020.06.07 |
C ++ 연산자의 암시 적 유형 변환 규칙 (0) | 2020.06.07 |
배열에 shared_ptr : 사용해야합니까? (0) | 2020.06.07 |