2016-09-01 15 views
1

SVProgressHUD에 UITapGestureRecognizer를 추가해야합니다. SVProgressHUD는 이미 -(void) dismiss;을 사용하여 닫을 수 있습니다. 이 코드는 초 단위로 애니메이션을 닫습니다.탭 제스처로 SVProgressHUD 닫기

- (void)dismiss { 
for (UIGestureRecognizer *gesture in [[[self class] sharedView] gestureRecognizers]) { 
    [[[self class] sharedView] removeGestureRecognizer:gesture]; 
} 

NSDictionary *userInfo = [self notificationUserInfo]; 
[[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDWillDisappearNotification 
                object:nil 
                userInfo:userInfo]; 

self.activityCount = 0; 
[UIView animateWithDuration:0.15 
         delay:0 
        options:UIViewAnimationCurveEaseIn | UIViewAnimationOptionAllowUserInteraction 
       animations:^{ 
        self.hudView.transform = CGAffineTransformScale(self.hudView.transform, 0.8, 0.8); 
        if(self.isClear) // handle iOS 7 UIToolbar not answer well to hierarchy opacity change 
         self.hudView.alpha = 0; 
        else 
         self.alpha = 0; 
       } 
       completion:^(BOOL finished){ 
        if(self.alpha == 0 || self.hudView.alpha == 0) { 
         self.alpha = 0; 
         self.hudView.alpha = 0; 

         [[NSNotificationCenter defaultCenter] removeObserver:self]; 
         [self cancelRingLayerAnimation]; 
         [self addTapGestureToDismiss]; 
         [_hudView removeFromSuperview]; 
         _hudView = nil; 

         [_overlayView removeFromSuperview]; 
         _overlayView = nil; 

         [_indefiniteAnimatedView removeFromSuperview]; 
         _indefiniteAnimatedView = nil; 


         UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil); 

         [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidDisappearNotification 
                      object:nil 
                      userInfo:userInfo]; 

         // Tell the rootViewController to update the StatusBar appearance 
         UIViewController *rootController = [[UIApplication sharedApplication] keyWindow].rootViewController; 
         if ([rootController respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) { 
          [rootController setNeedsStatusBarAppearanceUpdate]; 
         } 
         // uncomment to make sure UIWindow is gone from app.windows 
         //NSLog(@"%@", [UIApplication sharedApplication].windows); 
         //NSLog(@"keyWindow = %@", [UIApplication sharedApplication].keyWindow); 
        } 
       }]; 

}

내 생각 과정은 기각 방법에 tapGesture 코드를 추가하는 것입니다. 이것은 내가 지금까지 쓴 것입니다. 당신이 난 그냥 tapGesture를 초기화하고 있습니다 볼 수 있듯이

- (void)addTapGestureToDismiss { 

// Creation and initializer of the tap gesture 
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] 
             initWithTarget:self action:@selector(dismiss)]; 

// Specify that the gesture must be a single tap 
tapRecognizer.numberOfTapsRequired = 1; 

// Add the tap gesture recognizer to the view 
[[[self class] sharedView] addGestureRecognizer:tapRecognizer]; 

}

. 몇 군데에 배치하고 앱에 하나의 탭 만있는 문제가 발생했습니다. 나는 그 과정에서 자신을 혼란스럽게 만들었다. 해야할까요

  • 이 제스처를보기에 추가해야합니까?
  • 이 제스쳐를 추가 하시겠습니까? 나는이 솔루션 우연히이 질문을 기억 잠시 후
+0

이 부분을 자세히 살펴본 후 이미지를 보여주는 코드를 발견했습니다. 나는 작은 테스트 코드를 구현했다 :'if (self.imageView) { self.dismiss; }'이 테스트 코드를 구현 한 후 HudImage는 즉시 공개되었습니다. 그래서 지금 제 질문은 _objec-c_에서 제스처에 대한 if 문을 작성하는 방법입니다. 사용자가 탭을 시작하면이를 무시하고 말할 필요가 있습니다. – MyloTut

답변

2

UPDATE 2.0

, 그것은 지금까지 내가 테스트 한대로 작동합니다. viewWillAppear의 ViewController 클래스에 Observer를 추가하기 만하면됩니다. 이전의 대답처럼 라이브러리를 수정할 필요가 없습니다.

-(void)viewWillAppear:(BOOL)animated{ 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(tapToDismiss:) name:SVProgressHUDDidReceiveTouchEventNotification object:nil]; 
    //Other initializing 
} 
-(void)tapToDismiss:(NSNotification *)notification{ 
    [SVProgressHUD dismiss]; 
    //maybe other code to stop whatever your progress is 
} 

마스크 유형이 있어도 SVProgressHUD를 닫아야합니다.

완료 후 (예 : viewDidDisAppear에서) Observer를 제거하거나 앱 수명 기간 동안 Observer를 제거하려면 Observer를 제거하십시오.

[[NSNotificationCenter defaultCenter] removeObserver:self name:SVProgressHUDDidReceiveTouchEventNotification object:nil]; 

신용 : 당신이 그것을 사용하는 모든 뷰 컨트롤러에이 코드를 반복 할 필요가 없습니다 Z.Hung의 대답에 http://kevsaidwhat.blogspot.my/2013/06/cancel-svprogresshud-process-by-tapping.html

+0

해고 방법에 대해서는 아무 것도 변경할 수 없습니다.거기에 머무를 필요가 있거나 모든 허벅지가 화면에 남을 것입니다. 사용자가 선택하면 화면을 두드리는 기능을 추가하여 HUD를 닫아야합니다. view에 addTapToDismiss를 어떻게 붙이시겠습니까? – MyloTut

+0

아직 코드를 구현하지 않으셨습니까? dismiss 메소드는 viewController 클래스 내의 로컬 인스턴스 일 뿐이며 SVProgressHUD의 dismiss 메소드와 같은 메소드는 아닙니다. 화면이 두드려 질 때 단순히 SVProgressHUD의 해제를 호출합니다. 내 대답을 편집하여 옵션을 포함합니다 –

+0

명확하지 않은 경우 제 제안은 원본 SVProgressHUD 라이브러리 수정 (게시 된 해산 방법 포함)과 관련이 없습니다. addTapToDismiss를 viewController 클래스에 추가하고 필요할 때마다 호출하면됩니다. –

7

건물, 당신은 SVProgressHUD에 카테고리를 만들 수 있습니다.

사용

그냥이 범주를 가져오고 전화

[SVProgressHUD showDismissableErrorWithStatus:@"Error message here"];

코드

@interface SVProgressHUD (Dismissable) 

+ (void)showDismissableErrorWithStatus:(NSString*)status; 

@end 

@implementation SVProgressHUD (Dismissable) 

+ (void)showDismissableErrorWithStatus:(NSString*)status { 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleHUDTappedNotification:) name:SVProgressHUDDidReceiveTouchEventNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleHUDDisappearedNotification:) name:SVProgressHUDWillDisappearNotification object:nil]; 
    [SVProgressHUD showErrorWithStatus: status]; 
} 

#pragma mark - NSNotificationCenter 

+ (void)handleHUDTappedNotification: (NSNotification *)notification { 
    [SVProgressHUD dismiss]; 
} 

+ (void)handleHUDDisappearedNotification: (NSNotification *)notification { 
    [[NSNotificationCenter defaultCenter] removeObserver:self name:SVProgressHUDDidReceiveTouchEventNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] removeObserver:self name:SVProgressHUDWillDisappearNotification object:nil]; 

} 

@end 

스위프트 4

import SVProgressHUD 

/// Ref: https://stackoverflow.com/a/41111242/425694 
extension SVProgressHUD { 

    public static func showDismissableError(with status: String) { 
    let nc = NotificationCenter.default 
    nc.addObserver(
     self, selector: #selector(hudTapped(_:)), 
     name: NSNotification.Name.SVProgressHUDDidReceiveTouchEvent, 
     object: nil 
    ) 
    nc.addObserver(
     self, selector: #selector(hudDisappeared(_:)), 
     name: NSNotification.Name.SVProgressHUDWillDisappear, 
     object: nil 
    ) 
    SVProgressHUD.showError(withStatus: status) 
    SVProgressHUD.setDefaultMaskType(.clear) 
    } 

    @objc 
    private static func hudTapped(_ notification: Notification) { 
    SVProgressHUD.dismiss() 
    SVProgressHUD.setDefaultMaskType(.none) 
    } 

    @objc 
    private static func hudDisappeared(_ notification: Notification) { 
    let nc = NotificationCenter.default 
    nc.removeObserver(self, name: NSNotification.Name.SVProgressHUDDidReceiveTouchEvent, object: nil) 
    nc.removeObserver(self, name: NSNotification.Name.SVProgressHUDWillDisappear, object: nil) 
    SVProgressHUD.setDefaultMaskType(.none) 
    } 

} 
+0

나는 [SVProgressHUD setDefaultMaskType : SVProgressHUDMaskTypeClear]를 넣어야했다. showErrorWithStatus : .. 이후, 그것은 매력처럼 작동했습니다. 감사! – whitelionV

+0

그게 최선의 방법입니다. 먼저 SVProgressHUDMaskTypeClear를 넣어야합니다 ... TypeNone을 넣으면 어떻게됩니까? –