Steven преди 4 години
родител
ревизия
7147f1f627

+ 6 - 0
MusicGradeExam/MusicGradeExam.xcodeproj/project.pbxproj

@@ -302,6 +302,7 @@
 		278D113E24CFC6B600599421 /* ExamDeviceCheckView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 278D113D24CFC6B600599421 /* ExamDeviceCheckView.xib */; };
 		278D114124CFD58800599421 /* GuideNextPageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 278D114024CFD58800599421 /* GuideNextPageView.m */; };
 		278D114324CFD59B00599421 /* GuideNextPageView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 278D114224CFD59B00599421 /* GuideNextPageView.xib */; };
+		278D114624D0009000599421 /* KSGuideMaskView.m in Sources */ = {isa = PBXBuildFile; fileRef = 278D114524D0009000599421 /* KSGuideMaskView.m */; };
 		2794D1B024BC604800BAF6F3 /* VefiBodyView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2794D1AF24BC604800BAF6F3 /* VefiBodyView.m */; };
 		2794D1B224BC605600BAF6F3 /* VefiBodyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2794D1B124BC605600BAF6F3 /* VefiBodyView.xib */; };
 		2794D1B524BC662600BAF6F3 /* VeriCheckView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2794D1B424BC662600BAF6F3 /* VeriCheckView.m */; };
@@ -946,6 +947,8 @@
 		278D113F24CFD58800599421 /* GuideNextPageView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GuideNextPageView.h; sourceTree = "<group>"; };
 		278D114024CFD58800599421 /* GuideNextPageView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GuideNextPageView.m; sourceTree = "<group>"; };
 		278D114224CFD59B00599421 /* GuideNextPageView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GuideNextPageView.xib; sourceTree = "<group>"; };
+		278D114424D0009000599421 /* KSGuideMaskView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSGuideMaskView.h; sourceTree = "<group>"; };
+		278D114524D0009000599421 /* KSGuideMaskView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSGuideMaskView.m; sourceTree = "<group>"; };
 		2794D1AE24BC604800BAF6F3 /* VefiBodyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VefiBodyView.h; sourceTree = "<group>"; };
 		2794D1AF24BC604800BAF6F3 /* VefiBodyView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VefiBodyView.m; sourceTree = "<group>"; };
 		2794D1B124BC605600BAF6F3 /* VefiBodyView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = VefiBodyView.xib; sourceTree = "<group>"; };
@@ -2093,6 +2096,8 @@
 				274770F924BC0C0400181362 /* PressRecord */,
 				2747716B24BC0C0400181362 /* StateView.h */,
 				2747717824BC0C0400181362 /* StateView.m */,
+				278D114424D0009000599421 /* KSGuideMaskView.h */,
+				278D114524D0009000599421 /* KSGuideMaskView.m */,
 			);
 			path = Custom;
 			sourceTree = "<group>";
@@ -3097,6 +3102,7 @@
 				27A008B524BD97FE0002452B /* AudioRecordManager.m in Sources */,
 				2747721924BC0C0500181362 /* UIImage+Color.m in Sources */,
 				27EF3F2E24C0384E002068A2 /* HomeExamTicketCell.m in Sources */,
+				278D114624D0009000599421 /* KSGuideMaskView.m in Sources */,
 				2747722B24BC0C0500181362 /* KSAudioRecordFileManager.m in Sources */,
 				27A008D424BDA67F0002452B /* ModifyPhoneCheckController.m in Sources */,
 				2747726224BC0C0500181362 /* LLImageCache.m in Sources */,

+ 8 - 8
MusicGradeExam/MusicGradeExam/Define/PrefixHeader.pch

@@ -85,17 +85,17 @@
 
 //#ifdef DEBUG
 
-#define hostURL (@"https://test.kj.colexiu.com")
-#define SEALCLASSHOST (@"https://test.kj.colexiu.com/api-im")
+//#define hostURL (@"https://test.kj.colexiu.com")
+//#define SEALCLASSHOST (@"https://test.kj.colexiu.com/api-im")
+//#define WEBHOST (@"https://test.m.kj.colexiu.com")
+//#define JSPUSH_ENVIRONMENT (NO)
+//#define RCIM_KEY (@"8luwapkv84g3l")
+
+#define hostURL (@"http://192.168.3.28:8000")
+#define SEALCLASSHOST (@"http://192.168.3.28:8000/api-im")
 #define WEBHOST (@"https://test.m.kj.colexiu.com")
 #define JSPUSH_ENVIRONMENT (NO)
 #define RCIM_KEY (@"8luwapkv84g3l")
-
-//#define hostURL (@"http://192.168.3.28:8000")
-//#define SEALCLASSHOST (@"http://192.168.3.28:8000/api-im")
-//#define WEBHOST (@"http://mkjtest.dayaedu.com")
-//#define JSPUSH_ENVIRONMENT (NO)
-//#define RCIM_KEY (@"8luwapkv84g3l")
 //#else    // 线上
 
 //#define hostURL (@"https://online.dayaedu.com")

+ 1 - 1
MusicGradeExam/MusicGradeExam/KSRequestManager.m

@@ -733,7 +733,7 @@
 + (void)musicLibraryPageRequest:(NSString *)get tenantId:(NSString *)tenantId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
     NSString *url = [NSString stringWithFormat:@"%@%@", hostURL, @"/api-user/subject/studentQueryPage"];
     NSMutableDictionary *parm = [NSMutableDictionary dictionary];
-    [parm setValue:@"0" forKey:@"parentId"];
+//    [parm setValue:@"0" forKey:@"parentId"];
     [parm setValue:tenantId forKey:@"tenantId"];
     [self request:get url:url parm:parm success:success faliure:faliure];
 }

+ 34 - 0
MusicGradeExam/MusicGradeExam/Tools/Custom/KSGuideMaskView.h

@@ -0,0 +1,34 @@
+//
+//  KSGuideMaskView.h
+//  MusicGradeExam
+//
+//  Created by Kyle on 2020/7/28.
+//  Copyright © 2020 DayaMusic. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSGuideMaskView : UIView
+
+
+/// 初始化数据 一个个显示
+/// @param tipsArray 提示语
+/// @param rectArray 透明区域位置 UIBezierPath
+- (void)addTips:(NSArray *)tipsArray transparentRect:(NSArray *)rectArray shaperLayerIndex:(NSInteger)index;
+
+/**
+ 在指定view上显示蒙版(过渡动画) 不调用用此方法可使用 addSubview:自己添加展示
+ */
+- (void)showMaskViewInView:(UIView  * _Nullable)view;
+
+/**
+ *  销毁蒙版view(默认点击空白区自动销毁)
+ */
+- (void)dismissMaskView;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 227 - 0
MusicGradeExam/MusicGradeExam/Tools/Custom/KSGuideMaskView.m

@@ -0,0 +1,227 @@
+//
+//  KSGuideMaskView.m
+//  MusicGradeExam
+//
+//  Created by Kyle on 2020/7/28.
+//  Copyright © 2020 DayaMusic. All rights reserved.
+//
+
+#import "KSGuideMaskView.h"
+
+NSInteger countNum = 0;
+
+@interface KSGuideMaskView ()
+
+/// 图层
+@property (nonatomic, weak)   CAShapeLayer   *fillLayer;
+/// 路径
+@property (nonatomic, strong) UIBezierPath   *overlayPath;
+/// 透明区数组
+@property (nonatomic, strong) NSMutableArray *transparentPaths;
+
+/// 点击计数
+@property (nonatomic, assign) NSInteger index;
+
+/// tips数组
+@property (nonatomic, strong) NSMutableArray *tipsArray;
+
+@property (nonatomic, assign) NSInteger shaperLayerIndex;
+
+@property (nonatomic, strong) CAShapeLayer *shapeLayer;
+
+@end
+
+@implementation KSGuideMaskView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    
+    self = [super initWithFrame: [UIScreen mainScreen].bounds];
+    if (self) {
+        [self setUp];
+    }
+    return self;
+}
+
+- (void)setUp {
+    self.index = 0;
+    
+    self.backgroundColor = [UIColor clearColor];
+    
+    UIColor *maskColor = [UIColor colorWithWhite:0 alpha:0.61];
+    self.fillLayer.path      = self.overlayPath.CGPath;
+    self.fillLayer.fillRule  = kCAFillRuleEvenOdd;
+    self.fillLayer.fillColor = maskColor.CGColor;
+    
+    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapClickedMaskView)];
+    [self addGestureRecognizer:tapGesture];
+}
+
+- (void)layoutSubviews {
+    [super layoutSubviews];
+}
+
+
+- (void)addTips:(NSArray *)tipsArray transparentRect:(NSArray *)rectArray shaperLayerIndex:(NSInteger)index  {
+    if (tipsArray.count != rectArray.count) {
+        return;
+    }
+    self.shaperLayerIndex = index;
+    self.tipsArray = [NSMutableArray arrayWithArray:tipsArray];
+    self.transparentPaths = [NSMutableArray arrayWithArray:rectArray];
+    UIBezierPath *path = _transparentPaths[0];
+    [self addTips:_tipsArray[0] withFrame:path.bounds];
+    [self addTransparentPath:_transparentPaths[0]];
+    
+}
+
+- (void)tapClickedMaskView {
+    
+    _index++;
+    
+    if (_index < _tipsArray.count) {
+        
+        [self refreshMask];
+        [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
+        
+        UIBezierPath *path = _transparentPaths[_index];
+        [self addTransparentPath:_transparentPaths[_index]];
+        [self addTips:_tipsArray[_index] withFrame:path.bounds];
+    } else {
+        countNum = 0;
+        [self dismissMaskView];
+    }
+}
+
+- (void)addTips:(NSString *)tipsMessage withFrame:(CGRect)frame {
+    UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
+    label.text = tipsMessage;
+    label.textAlignment = NSTextAlignmentCenter;
+    label.font = [UIFont systemFontOfSize:15.0f];
+    label.textColor = HexRGB(0xffffff);
+    [self addSubview:label];
+    [label mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.mas_equalTo(self);
+        make.top.mas_equalTo(CGRectGetMaxY(frame) + 20);
+    }];
+    
+    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
+    button.layer.borderWidth = 1.0f;
+    button.layer.borderColor = HexRGB(0xffffff).CGColor;
+    button.layer.cornerRadius = 20.0f;
+    [button setTitle:@"知道啦" forState:UIControlStateNormal];
+    button.userInteractionEnabled = NO;
+//    [button addTarget:self action:@selector(tapClickedMaskView) forControlEvents:UIControlEventTouchUpInside];
+    [self addSubview:button];
+    [button mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.width.mas_equalTo(110);
+        make.height.mas_equalTo(40);
+        make.top.mas_equalTo(label.mas_bottom).offset(28);
+        make.centerX.mas_equalTo(self);
+    }];
+}
+
+- (void)addTransparentPath:(UIBezierPath *)transparentPath {
+    
+    [self.overlayPath appendPath:transparentPath];
+    self.fillLayer.path = self.overlayPath.CGPath;
+    
+    if (_index == self.shaperLayerIndex) {
+        CGRect frame = transparentPath.bounds;
+        frame.size.width += 20;
+        frame.size.height += 20;
+        frame.origin.x -= 10;
+        frame.origin.y -= 10;
+        UIBezierPath *newPath = [UIBezierPath bezierPathWithOvalInRect:frame];
+
+        _shapeLayer = [CAShapeLayer layer];
+        _shapeLayer.frame = self.bounds;
+        _shapeLayer.path = newPath.CGPath;
+        _shapeLayer.lineWidth = 2.0f;
+        _shapeLayer.strokeColor = HexRGB(0xffffff).CGColor;
+        _shapeLayer.fillColor = [UIColor clearColor].CGColor;
+        _shapeLayer.lineDashPattern = @[@(10), @(10)];
+        [self.layer addSublayer:_shapeLayer];
+    }
+    else {
+        if (_shapeLayer) {
+            [_shapeLayer removeFromSuperlayer];
+            _shapeLayer = nil;
+        }
+    }
+}
+
+#pragma mark - 显示/隐藏
+
+- (void)showMaskViewInView:(UIView *)view{
+    
+    self.alpha = 0;
+    if (view != nil) {
+        [view addSubview:self];
+    }else{
+        [[UIApplication sharedApplication].keyWindow addSubview:self];
+    }
+    [UIView animateWithDuration:0.3 animations:^{
+        self.alpha = 1;
+    }];
+}
+
+- (void)dismissMaskView{
+    [UIView animateWithDuration:0.3 animations:^{
+        self.alpha = 0;
+    } completion:^(BOOL finished) {
+        [self removeFromSuperview];
+    }];
+}
+
+- (void)refreshMask {
+    
+    UIBezierPath *overlayPath = [self generateOverlayPath];
+    self.overlayPath = overlayPath;
+}
+
+- (UIBezierPath *)generateOverlayPath {
+    
+    UIBezierPath *overlayPath = [UIBezierPath bezierPathWithRect:self.bounds];
+    [overlayPath setUsesEvenOddFillRule:YES];
+    
+    return overlayPath;
+}
+
+#pragma mark - 懒加载Getter Methods
+
+- (UIBezierPath *)overlayPath {
+    if (!_overlayPath) {
+        _overlayPath = [self generateOverlayPath];
+    }
+    
+    return _overlayPath;
+}
+
+- (CAShapeLayer *)fillLayer {
+    if (!_fillLayer) {
+        CAShapeLayer *fillLayer = [CAShapeLayer layer];
+        fillLayer.frame = self.bounds;
+        [self.layer addSublayer:fillLayer];
+        
+        _fillLayer = fillLayer;
+    }
+    
+    return _fillLayer;
+}
+
+- (NSMutableArray *)transparentPaths {
+    if (!_transparentPaths) {
+        _transparentPaths = [NSMutableArray array];
+    }
+    return _transparentPaths;
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 60 - 1
MusicGradeExam/MusicGradeExam/UI/Exam/Controller/WaitExamViewController.m

@@ -12,8 +12,9 @@
 #import "OnlineRoomManager.h"
 #import "RecordExamViewController.h"
 #import "ExamGuideViewController.h"
+#import "KSGuideMaskView.h"
 
-@interface WaitExamViewController ()
+@interface WaitExamViewController ()<UIScrollViewDelegate>
 
 @property (nonatomic, strong) WaitExamBodyView *bodyView;
 
@@ -67,8 +68,46 @@
         return;
     }
     [self requestDataWithHub:YES];
+    BOOL hasAppear = UserDefaultBoolForKey(@"examTipsTop");
+    if (hasAppear == NO) {
+        [self addIntroduceView];
+    }
+}
+
+- (void)addIntroduceView {
+    UserDefaultSetBoolForKey(YES, @"examTipsTop");
+    
+    NSArray *tipsArray = @[@"考场开启后,才可已进行签到,签到后排考", @"展示为当前考场的排考信息"];
+    CGRect rect1 = [self.bodyView convertRect:self.bodyView.signButton.frame toView:[UIApplication sharedApplication].keyWindow];
+    rect1.origin.y += (kNaviBarHeight-5);
+    rect1.origin.x -= 5;
+    rect1.size.width += 10;
+    rect1.size.height += 10;
+    UIBezierPath *pathOne = [UIBezierPath bezierPathWithOvalInRect:rect1];
+    CGRect rect2 = [self.bodyView convertRect:self.bodyView.examMessageView.frame toView:[UIApplication sharedApplication].keyWindow];
+    rect2.origin.y += kNaviBarHeight;
+    UIBezierPath *pathSecond = [UIBezierPath bezierPathWithRect:rect2];
+    
+    NSArray *bezierArray = @[pathOne,pathSecond];
+    
+    KSGuideMaskView *guideView = [[KSGuideMaskView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight)];
+    [guideView addTips:tipsArray transparentRect:bezierArray shaperLayerIndex:0];
+    [guideView showMaskViewInView:nil];
+}
+
+
+- (void)showBottomTips {
+    UserDefaultSetBoolForKey(YES, @"examTipsBottom");
+    NSArray *tipsArray = @[@"展示为线上考试的注意事项"];
+    CGRect rect3 = [self.bodyView convertRect:self.bodyView.tipsView.frame toView:[UIApplication sharedApplication].keyWindow];
+    UIBezierPath *pathThree = [UIBezierPath bezierPathWithRect:rect3];
+    NSArray *bezierArray = @[pathThree];
+    KSGuideMaskView *guideView = [[KSGuideMaskView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight)];
+    [guideView addTips:tipsArray transparentRect:bezierArray shaperLayerIndex:-1];
+    [guideView showMaskViewInView:nil];
 }
 
+
 - (void)requestDataWithHub:(BOOL)needHub {
     if (needHub) {
        [self showhud];
@@ -106,6 +145,8 @@
 - (void)configUI {
     self.scrollView.backgroundColor = HexRGB(0xf3f4f8);
     self.scrollView.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight - kTabBarHeight - iPhoneXSafeBottomMargin);
+    self.scrollView.delegate = self;
+    self.scrollView.bounces = NO;
     _bodyView = [WaitExamBodyView shareInstance];
     CGFloat viewHeight = 206 + 200 + 19 + 204 + 50 + 21 + 9 + 50 + 27;
     viewHeight = viewHeight > kScreenHeight - kTabBarHeight - iPhoneXSafeBottomMargin ? viewHeight : kScreenHeight - kTabBarHeight - iPhoneXSafeBottomMargin;
@@ -189,6 +230,24 @@
 - (void)dealloc {
     [[NSNotificationCenter defaultCenter] removeObserver:self];
 }
+
+
+
+- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
+    CGPoint offset = scrollView.contentOffset;
+    CGRect bounds = scrollView.bounds;
+    CGSize size = scrollView.contentSize;
+    UIEdgeInsets inset = scrollView.contentInset;
+    CGFloat currentOffset = offset.y + bounds.size.height - inset.bottom;
+    CGFloat maximumOffset = size.height;
+    if((maximumOffset - currentOffset) < 40.0) {
+        BOOL hasAppear = UserDefaultBoolForKey(@"examTipsBottom");
+        if (hasAppear == NO) {
+            [self showBottomTips];
+        }
+    }
+}
+
 /*
 #pragma mark - Navigation
 

+ 4 - 1
MusicGradeExam/MusicGradeExam/UI/Exam/View/WaitExamBodyView.h

@@ -27,8 +27,11 @@ NS_ASSUME_NONNULL_BEGIN
 
 @property (weak, nonatomic) IBOutlet UIButton *joinButton;
 
-- (CGFloat)configTipsHeight:(NSString *)tipsMessage;
+@property (weak, nonatomic) IBOutlet UIView *examMessageView;
+
+@property (weak, nonatomic) IBOutlet UIView *tipsView;
 
+- (CGFloat)configTipsHeight:(NSString *)tipsMessage;
 
 + (instancetype)shareInstance;
 

+ 2 - 0
MusicGradeExam/MusicGradeExam/UI/Exam/View/WaitExamBodyView.xib

@@ -275,11 +275,13 @@
             <connections>
                 <outlet property="classDate" destination="qLV-gz-q1k" id="deW-pB-idj"/>
                 <outlet property="classTime" destination="Czx-Hb-wZ8" id="irw-eT-XKg"/>
+                <outlet property="examMessageView" destination="Pa9-Km-YvF" id="xvc-mw-5ne"/>
                 <outlet property="joinButton" destination="I8H-IY-JIX" id="cAC-Ad-PuS"/>
                 <outlet property="signButton" destination="WEa-ER-E4J" id="Ft8-JM-Rw6"/>
                 <outlet property="signDescLabel" destination="O3Y-5U-nUH" id="tBU-Y1-qvd"/>
                 <outlet property="subjectLabel" destination="cOI-UA-7JY" id="95e-BG-AVB"/>
                 <outlet property="tipsLabel" destination="LPU-2y-DR5" id="b5a-fX-xS4"/>
+                <outlet property="tipsView" destination="rEr-rK-lTU" id="QFY-uH-NJW"/>
                 <outlet property="waitLabel" destination="KQk-Oi-2gF" id="m6Y-Ea-Z5h"/>
             </connections>
             <point key="canvasLocation" x="131.8840579710145" y="101.78571428571428"/>