187 lines
4.9 KiB
Objective-C
187 lines
4.9 KiB
Objective-C
|
|
|
|
// Created by lvjunhang on 2019/5/21.
|
|
// Copyright © 2023 YUMI. All rights reserved.
|
|
|
|
|
|
#import "TTPopupManagerService.h"
|
|
|
|
#import <FFPopup/FFPopup.h>
|
|
|
|
@interface TTPopupManagerService ()
|
|
|
|
@property (nonatomic, strong) NSMutableArray< id<TTPopupServiceProtocol> > *queue;
|
|
|
|
|
|
@property (nonatomic, assign, getter=isShowingPopup) BOOL showingPopup;
|
|
|
|
@end
|
|
|
|
@implementation TTPopupManagerService
|
|
|
|
#pragma mark - Life Cycle
|
|
+ (instancetype)sharedInstance {
|
|
static TTPopupManagerService *instance = nil;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
instance = [[self alloc] init];
|
|
});
|
|
|
|
return instance;
|
|
}
|
|
|
|
- (instancetype)init {
|
|
if (self = [super init]) {
|
|
_queue = [NSMutableArray array];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
#pragma mark - TTPopupManagerServiceProtocol
|
|
- (void)addPopupService:(id<TTPopupServiceProtocol>)service {
|
|
if (![service conformsToProtocol:@protocol(TTPopupServiceProtocol)]) {
|
|
return;
|
|
}
|
|
if ([_queue containsObject:service]) {
|
|
return;
|
|
}
|
|
NSInteger insertPosition = [self insertPositionForPopupService:service];
|
|
if (insertPosition == NSNotFound) {
|
|
return;
|
|
}
|
|
[_queue insertObject:service atIndex:insertPosition];
|
|
|
|
if (_currentPopupService == nil && _queue.count == 1) {
|
|
[self showPopup];
|
|
}
|
|
}
|
|
|
|
- (void)removePopupService {
|
|
|
|
|
|
if (!self.isShowingPopup) {
|
|
return;
|
|
}
|
|
|
|
if (_currentPopupService == nil) {
|
|
return;
|
|
}
|
|
|
|
if (_queue.count > 0) {
|
|
[_queue removeObjectAtIndex:0];
|
|
}
|
|
|
|
[FFPopup dismissPopupForView:_currentPopupService.contentView animated:YES];
|
|
_currentPopupService = nil;
|
|
}
|
|
|
|
|
|
- (void)removeSourceWhenTouchMaskView {
|
|
if (_currentPopupService == nil) {
|
|
return;
|
|
}
|
|
if (_queue.count > 0) {
|
|
[_queue removeObjectAtIndex:0];
|
|
}
|
|
_currentPopupService = nil;
|
|
}
|
|
|
|
#pragma mark - Private Methods
|
|
|
|
|
|
- (void)showPopup {
|
|
if (self.isShowingPopup) {
|
|
return;
|
|
}
|
|
if (_currentPopupService) {
|
|
return;
|
|
}
|
|
if (_queue.count == 0) {
|
|
return;
|
|
}
|
|
id<TTPopupServiceProtocol> popupService = _queue.firstObject;
|
|
if (![popupService conformsToProtocol:@protocol(TTPopupServiceProtocol)]) {
|
|
return;
|
|
}
|
|
_currentPopupService = popupService;
|
|
FFPopupHorizontalLayout horizontalLayout = FFPopupHorizontalLayout_Center;
|
|
FFPopupVerticalLayout verticalLayout = FFPopupVerticalLayout_Center;
|
|
FFPopupShowType showType = (FFPopupShowType)popupService.showType;
|
|
FFPopupDismissType dismissType = FFPopupDismissType_GrowOut;
|
|
if (popupService.style == TTPopupStyleActionSheet) {
|
|
verticalLayout = FFPopupVerticalLayout_Bottom;
|
|
showType = FFPopupShowType_SlideInFromBottom;
|
|
dismissType = FFPopupDismissType_SlideOutToBottom;
|
|
}
|
|
FFPopup *popup = [FFPopup popupWithContentView:popupService.contentView];
|
|
popup.showType = showType;
|
|
popup.dismissType = dismissType;
|
|
popup.maskType = FFPopupMaskType_Dimmed;
|
|
popup.dimmedMaskAlpha = popupService.maskBackgroundAlpha;
|
|
popup.shouldDismissOnBackgroundTouch = popupService.shouldDismissOnBackgroundTouch;
|
|
|
|
[popup showWithLayout:FFPopupLayoutMake(horizontalLayout, verticalLayout) duration:0.0];
|
|
__weak typeof(self) weakSelf = self;
|
|
|
|
|
|
popup.didFinishDismissingBlock = ^{
|
|
__strong typeof(weakSelf) strongSelf = weakSelf;
|
|
BOOL isDismissOnBackgroundTouch = strongSelf.currentPopupService != nil;
|
|
if (isDismissOnBackgroundTouch) {
|
|
|
|
[self removeSourceWhenTouchMaskView];
|
|
}
|
|
if (popupService.didFinishDismissHandler) {
|
|
popupService.didFinishDismissHandler(isDismissOnBackgroundTouch);
|
|
}
|
|
|
|
strongSelf.showingPopup = NO;
|
|
|
|
[strongSelf showPopup];
|
|
};
|
|
|
|
popup.didFinishShowingBlock = ^{
|
|
|
|
self.showingPopup = YES;
|
|
if (popupService.didFinishShowingHandler) {
|
|
popupService.didFinishShowingHandler();
|
|
}
|
|
};
|
|
}
|
|
|
|
|
|
- (NSInteger)insertPositionForPopupService:(id<TTPopupServiceProtocol>)service {
|
|
__block NSInteger result = NSNotFound;
|
|
if (service == nil) {
|
|
return result;
|
|
}
|
|
if (_queue.count == 0) {
|
|
return 0;
|
|
}
|
|
|
|
if (service.shouldFilterPopup && service.filterIdentifier.length > 0) {
|
|
BOOL filterFlag = NO;
|
|
for (id<TTPopupServiceProtocol> serv in _queue) {
|
|
if ([serv.filterIdentifier isEqualToString:service.filterIdentifier]) {
|
|
filterFlag = YES;
|
|
break;
|
|
}
|
|
}
|
|
if (filterFlag) {
|
|
return result;
|
|
}
|
|
}
|
|
[_queue enumerateObjectsUsingBlock:^(id<TTPopupServiceProtocol> _Nonnull model, NSUInteger idx, BOOL * _Nonnull stop) {
|
|
|
|
if (service.priority > model.priority) {
|
|
result = idx;
|
|
*stop = YES;
|
|
}
|
|
}];
|
|
|
|
result = MIN(result, _queue.count);
|
|
return result;
|
|
}
|
|
|
|
@end
|