diff --git a/iCemarose.xcodeproj/project.pbxproj b/iCemarose.xcodeproj/project.pbxproj index 765ef29..1f03dec 100644 --- a/iCemarose.xcodeproj/project.pbxproj +++ b/iCemarose.xcodeproj/project.pbxproj @@ -101,6 +101,10 @@ C02986901F0F2663002EB25F /* KWMWishCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C029868E1F0F2663002EB25F /* KWMWishCell.xib */; }; C02C5A931FD54C7D00E32290 /* KWMRecommendView.m in Sources */ = {isa = PBXBuildFile; fileRef = C02C5A901FD54C7C00E32290 /* KWMRecommendView.m */; }; C02C5A941FD54C7D00E32290 /* KWMRecommendView.xib in Resources */ = {isa = PBXBuildFile; fileRef = C02C5A911FD54C7C00E32290 /* KWMRecommendView.xib */; }; + C02C5A9E1FD6944500E32290 /* TPKeyboardAvoidingCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = C02C5A971FD6944500E32290 /* TPKeyboardAvoidingCollectionView.m */; }; + C02C5A9F1FD6944500E32290 /* TPKeyboardAvoidingScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = C02C5A991FD6944500E32290 /* TPKeyboardAvoidingScrollView.m */; }; + C02C5AA01FD6944500E32290 /* TPKeyboardAvoidingTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = C02C5A9B1FD6944500E32290 /* TPKeyboardAvoidingTableView.m */; }; + C02C5AA11FD6944500E32290 /* UIScrollView+TPKeyboardAvoidingAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = C02C5A9D1FD6944500E32290 /* UIScrollView+TPKeyboardAvoidingAdditions.m */; }; C02C7D801E640D82008DC29C /* libWeChatSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C02C7D7B1E640D82008DC29C /* libWeChatSDK.a */; }; C02C7D811E640D82008DC29C /* README.txt in Resources */ = {isa = PBXBuildFile; fileRef = C02C7D7C1E640D82008DC29C /* README.txt */; }; C02C7D831E640FBF008DC29C /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C02C7D821E640FBF008DC29C /* SystemConfiguration.framework */; }; @@ -547,6 +551,14 @@ C02C5A901FD54C7C00E32290 /* KWMRecommendView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KWMRecommendView.m; sourceTree = "<group>"; }; C02C5A911FD54C7C00E32290 /* KWMRecommendView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KWMRecommendView.xib; sourceTree = "<group>"; }; C02C5A921FD54C7D00E32290 /* KWMRecommendView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KWMRecommendView.h; sourceTree = "<group>"; }; + C02C5A961FD6944500E32290 /* TPKeyboardAvoidingCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPKeyboardAvoidingCollectionView.h; sourceTree = "<group>"; }; + C02C5A971FD6944500E32290 /* TPKeyboardAvoidingCollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPKeyboardAvoidingCollectionView.m; sourceTree = "<group>"; }; + C02C5A981FD6944500E32290 /* TPKeyboardAvoidingScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPKeyboardAvoidingScrollView.h; sourceTree = "<group>"; }; + C02C5A991FD6944500E32290 /* TPKeyboardAvoidingScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPKeyboardAvoidingScrollView.m; sourceTree = "<group>"; }; + C02C5A9A1FD6944500E32290 /* TPKeyboardAvoidingTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPKeyboardAvoidingTableView.h; sourceTree = "<group>"; }; + C02C5A9B1FD6944500E32290 /* TPKeyboardAvoidingTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPKeyboardAvoidingTableView.m; sourceTree = "<group>"; }; + C02C5A9C1FD6944500E32290 /* UIScrollView+TPKeyboardAvoidingAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIScrollView+TPKeyboardAvoidingAdditions.h"; sourceTree = "<group>"; }; + C02C5A9D1FD6944500E32290 /* UIScrollView+TPKeyboardAvoidingAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIScrollView+TPKeyboardAvoidingAdditions.m"; sourceTree = "<group>"; }; C02C7D7B1E640D82008DC29C /* libWeChatSDK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libWeChatSDK.a; sourceTree = "<group>"; }; C02C7D7C1E640D82008DC29C /* README.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.txt; sourceTree = "<group>"; }; C02C7D7D1E640D82008DC29C /* WechatAuthSDK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WechatAuthSDK.h; sourceTree = "<group>"; }; @@ -1241,6 +1253,21 @@ path = Cell; sourceTree = "<group>"; }; + C02C5A951FD6944500E32290 /* TPKeyboardAvoiding */ = { + isa = PBXGroup; + children = ( + C02C5A961FD6944500E32290 /* TPKeyboardAvoidingCollectionView.h */, + C02C5A971FD6944500E32290 /* TPKeyboardAvoidingCollectionView.m */, + C02C5A981FD6944500E32290 /* TPKeyboardAvoidingScrollView.h */, + C02C5A991FD6944500E32290 /* TPKeyboardAvoidingScrollView.m */, + C02C5A9A1FD6944500E32290 /* TPKeyboardAvoidingTableView.h */, + C02C5A9B1FD6944500E32290 /* TPKeyboardAvoidingTableView.m */, + C02C5A9C1FD6944500E32290 /* UIScrollView+TPKeyboardAvoidingAdditions.h */, + C02C5A9D1FD6944500E32290 /* UIScrollView+TPKeyboardAvoidingAdditions.m */, + ); + path = TPKeyboardAvoiding; + sourceTree = "<group>"; + }; C02C7D7A1E640D82008DC29C /* WeChat */ = { isa = PBXGroup; children = ( @@ -1509,6 +1536,7 @@ C034E6C51D6AECF9006EE129 /* View */ = { isa = PBXGroup; children = ( + C02C5A951FD6944500E32290 /* TPKeyboardAvoiding */, C0CCB3B51EEA520C00BC2FB8 /* FilterView */, C0DD53251EE55190002D1E0C /* Cell */, C0DD53261EE55190002D1E0C /* Loading */, @@ -2684,6 +2712,7 @@ C034E8621D6B10A0006EE129 /* PBPGView.m in Sources */, C0243BC01EFBD5A10013CFA7 /* KWMRightProductCell.m in Sources */, C02C7DB41E67B56D008DC29C /* KWMFilterHeaderView.m in Sources */, + C02C5A9E1FD6944500E32290 /* TPKeyboardAvoidingCollectionView.m in Sources */, 80ED0A371D93840A00B28DF2 /* DB_shopCart.xcdatamodeld in Sources */, C0DD53391EE55190002D1E0C /* KWMSplashView.m in Sources */, 80E844271D7FB0FF0042AED2 /* KWMRuleView.m in Sources */, @@ -2704,6 +2733,7 @@ 807AF4A51DC984950000A326 /* KWMCustomerResult.m in Sources */, DA8B97801F58F816002FC38A /* SDImageCache+Resize.m in Sources */, C066650F1D7675FC00F02EF4 /* KWMAboutUsVC.m in Sources */, + C02C5AA11FD6944500E32290 /* UIScrollView+TPKeyboardAvoidingAdditions.m in Sources */, 807AF4A31DC984950000A326 /* KWMBlogResult.m in Sources */, C0CC14081D7823B0007B5986 /* KWMSizeCell.m in Sources */, C057C77D1F172D4C00B95034 /* KWMMidDetailView.m in Sources */, @@ -2724,6 +2754,7 @@ C091EE331DDB1FC500A382B9 /* KWMAppVersion.m in Sources */, C0CC14041D7823B0007B5986 /* KWMDeleteView.m in Sources */, C0028ECB1F0E2B3500744C14 /* KWMAdditionalListResult.m in Sources */, + C02C5A9F1FD6944500E32290 /* TPKeyboardAvoidingScrollView.m in Sources */, 8091DFA11D6E878C0020519C /* KWMGuideVC.m in Sources */, C034E84A1D6B10A0006EE129 /* UIImage+Color.m in Sources */, 801230F21DD30704008C7904 /* KWMSearchBrandsCell.m in Sources */, @@ -2777,6 +2808,7 @@ DA4E36951F1726B80007E4D0 /* UIViewController+HTTP.m in Sources */, 807AF4A71DC984950000A326 /* KWMProducts.m in Sources */, C0F5868A1E24F820001248E2 /* KWMSelectedGoodsVC.m in Sources */, + C02C5AA01FD6944500E32290 /* TPKeyboardAvoidingTableView.m in Sources */, C034E8661D6B10A0006EE129 /* PhotoItemView.m in Sources */, 9B166F511ED6DBCF003E9F03 /* KWMHttpUtil.m in Sources */, C034E6D91D6AEF1B006EE129 /* KWMStringUtil.m in Sources */, diff --git a/iCemarose/Class/Api/KWMAPIManager.m b/iCemarose/Class/Api/KWMAPIManager.m index 5d102f0..4b71b24 100644 --- a/iCemarose/Class/Api/KWMAPIManager.m +++ b/iCemarose/Class/Api/KWMAPIManager.m @@ -277,7 +277,7 @@ static NSString *const passwordTest = @"9e84aae218c57cdf0762763c4cf5a651"; } } if(isUseClientAuth){ - [sessionManager.requestSerializer setValue:@"Basic YzJmNmZhZTk3NzQxZWE2ZGI0Y2FkN2FlOGY3MGZlZjM==" forHTTPHeaderField:@"Authorization"]; + [sessionManager.requestSerializer setValue:Order_API_Auth forHTTPHeaderField:@"Authorization"]; } return sessionManager; } @@ -1149,7 +1149,7 @@ static NSString *const passwordTest = @"9e84aae218c57cdf0762763c4cf5a651"; } /** - * 清空愿望单 API + * 获取所以订单 API * @param customer_id 用户ID * @param customer_email 用户邮箱 * @param shop 店铺名(cemarose-test.myshopify.com) @@ -1158,7 +1158,7 @@ static NSString *const passwordTest = @"9e84aae218c57cdf0762763c4cf5a651"; success:(void(^)(NSURLSessionDataTask *task,KWMOrderListResult *result))success failure:(void(^)(NSURLSessionDataTask *task,NSError *error))failure{ NSString *apiPath = [NSString stringWithFormat:@"https://%@/customer/orders/custom-orders",WishList_API_DOMAIN]; -// apiPath = @"https://peter.tofnews.com/customer/orders/custom-orders"; +// apiPath = @"https://test.cemarose.com/customer/orders/custom-orders"; return [self startSessionTask:KWMHTTPMethodGET apiPath:apiPath parameters:parameters diff --git a/iCemarose/Class/UI/Mine/KWMOrderVC.m b/iCemarose/Class/UI/Mine/KWMOrderVC.m index 835c929..4e03ce0 100644 --- a/iCemarose/Class/UI/Mine/KWMOrderVC.m +++ b/iCemarose/Class/UI/Mine/KWMOrderVC.m @@ -225,8 +225,8 @@ }; [self.api getOrderList:parameters success:^(NSURLSessionDataTask *task, KWMOrderListResult *result) { [weakSelf hideLoading]; - if(!result.code || result.code.integerValue != 1000){ - if(result.message){ + if(!result || !result.code || result.code.integerValue != 1000){ + if(result && result.message){ [weakSelf showToast:result.message]; } return; diff --git a/iCemarose/Class/UI/ShopCart/KWMBeforePayVC.h b/iCemarose/Class/UI/ShopCart/KWMBeforePayVC.h index 5d67520..c70c95d 100644 --- a/iCemarose/Class/UI/ShopCart/KWMBeforePayVC.h +++ b/iCemarose/Class/UI/ShopCart/KWMBeforePayVC.h @@ -16,7 +16,7 @@ #import "KWMPayTypeVC.h" #import "KWMBeforePayData.h" -@interface KWMBeforePayVC : KWMBaseVC<KWMGiftCardDelegate,KWMSelectAddressDelegate,KWMSelectShippingRateDelegate,UITextFieldDelegate> +@interface KWMBeforePayVC : KWMBaseVC<KWMGiftCardDelegate,KWMSelectAddressDelegate,KWMSelectShippingRateDelegate> //沒有默認地址時,高度為37,有地址時,高度為90 @property(nonatomic,weak) IBOutlet NSLayoutConstraint *vAddressHeight; @@ -50,10 +50,6 @@ @property (weak, nonatomic) IBOutlet UIButton *btnDiscountEdit; @property (weak, nonatomic) IBOutlet UITextField *tfDiscount; - -@property (weak, nonatomic) IBOutlet UIButton *btnBg; - -@property (weak, nonatomic) IBOutlet NSLayoutConstraint *marginTopContent; //价格 @property (weak, nonatomic) IBOutlet UILabel *lbTotalPrice; diff --git a/iCemarose/Class/UI/ShopCart/KWMBeforePayVC.m b/iCemarose/Class/UI/ShopCart/KWMBeforePayVC.m index 339233f..c9929be 100644 --- a/iCemarose/Class/UI/ShopCart/KWMBeforePayVC.m +++ b/iCemarose/Class/UI/ShopCart/KWMBeforePayVC.m @@ -482,24 +482,6 @@ [self startCheckout]; } -#pragma mark - UITextFieldDelegate --(BOOL)textFieldShouldBeginEditing:(UITextField *)textField{ - self.marginTopContent.constant = 22 - 200; - [UIView animateWithDuration:0.5 animations:^{ - [self.view layoutIfNeeded]; - }]; - return YES; -} - -//键盘弹出 --(void)keyboardWillHide:(NSNotification *)notification{ - self.marginTopContent.constant = 22; - [UIView animateWithDuration:0.5 animations:^{ - [self.view layoutIfNeeded]; - }]; - -} - -(void)startCheckout{ if(self.checkout == nil){ [self showToast:@"未成功初始化订单"]; diff --git a/iCemarose/Class/UI/ShopCart/ShopCart.storyboard b/iCemarose/Class/UI/ShopCart/ShopCart.storyboard index 87f3b41..bc57124 100644 --- a/iCemarose/Class/UI/ShopCart/ShopCart.storyboard +++ b/iCemarose/Class/UI/ShopCart/ShopCart.storyboard @@ -645,11 +645,11 @@ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> - <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lUQ-J5-kOq"> + <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lUQ-J5-kOq" customClass="TPKeyboardAvoidingScrollView"> <rect key="frame" x="0.0" y="0.0" width="375" height="549"/> <subviews> - <view contentMode="scaleToFill" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="BlA-Cz-DcE"> - <rect key="frame" x="0.0" y="-222" width="374" height="562"/> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="BlA-Cz-DcE"> + <rect key="frame" x="0.0" y="0.0" width="374" height="562"/> <subviews> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="寄送地址" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="MY5-C7-Kcb"> <rect key="frame" x="30" y="22" width="60" height="21"/> @@ -763,13 +763,6 @@ <color key="textColor" red="0.30588235289999999" green="0.30588235289999999" blue="0.30588235289999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <nil key="highlightedColor"/> </label> - <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Jh2-0e-Ceb" userLabel="line"> - <rect key="frame" x="0.0" y="39" width="374" height="1"/> - <color key="backgroundColor" red="0.84705882349999995" green="0.85882352939999995" blue="0.87058823529999996" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> - <constraints> - <constraint firstAttribute="height" constant="1" id="HTJ-Ty-IZI"/> - </constraints> - </view> <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_choose_sel" translatesAutoresizingMaskIntoConstraints="NO" id="qA8-Up-cG8"> <rect key="frame" x="329" y="12.5" width="15" height="15"/> <constraints> @@ -781,11 +774,8 @@ <color key="backgroundColor" red="0.95686274510000002" green="0.96078431369999995" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <constraints> <constraint firstAttribute="height" constant="40" id="32w-IK-79o"/> - <constraint firstItem="Jh2-0e-Ceb" firstAttribute="leading" secondItem="0t9-CT-iWp" secondAttribute="leading" id="QDx-29-HUV"/> <constraint firstAttribute="bottom" secondItem="ZTw-Ec-fab" secondAttribute="bottom" id="V7G-gU-cS8"/> - <constraint firstAttribute="bottom" secondItem="Jh2-0e-Ceb" secondAttribute="bottom" id="Wdy-jS-ub1"/> <constraint firstItem="ZTw-Ec-fab" firstAttribute="top" secondItem="0t9-CT-iWp" secondAttribute="top" id="gyr-wF-w2J"/> - <constraint firstAttribute="trailing" secondItem="Jh2-0e-Ceb" secondAttribute="trailing" id="hUA-Rx-NPH"/> <constraint firstItem="qA8-Up-cG8" firstAttribute="centerY" secondItem="0t9-CT-iWp" secondAttribute="centerY" id="j47-nG-wrd"/> <constraint firstAttribute="trailing" secondItem="qA8-Up-cG8" secondAttribute="trailing" constant="30" id="kYM-dI-919"/> <constraint firstItem="ZTw-Ec-fab" firstAttribute="leading" secondItem="0t9-CT-iWp" secondAttribute="leading" constant="30" id="sXw-lU-ohe"/> @@ -810,13 +800,6 @@ <color key="textColor" red="0.30588235289999999" green="0.30588235289999999" blue="0.30588235289999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <nil key="highlightedColor"/> </label> - <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="B9t-Fw-Xfq" userLabel="line"> - <rect key="frame" x="0.0" y="39" width="374" height="1"/> - <color key="backgroundColor" red="0.84705882349999995" green="0.85882352939999995" blue="0.87058823529999996" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> - <constraints> - <constraint firstAttribute="height" constant="1" id="E5z-EV-AmJ"/> - </constraints> - </view> <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_choose_nor" translatesAutoresizingMaskIntoConstraints="NO" id="RK9-ZZ-KNx"> <rect key="frame" x="329" y="12.5" width="15" height="15"/> <constraints> @@ -828,22 +811,17 @@ <color key="backgroundColor" red="0.95686274510000002" green="0.96078431369999995" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <constraints> <constraint firstItem="I1W-Yg-7VA" firstAttribute="top" secondItem="SQP-ML-8dW" secondAttribute="top" id="6Kz-Cu-2H6"/> - <constraint firstAttribute="bottom" secondItem="B9t-Fw-Xfq" secondAttribute="bottom" id="8Pe-Nl-bDS"/> - <constraint firstItem="B9t-Fw-Xfq" firstAttribute="leading" secondItem="I1W-Yg-7VA" secondAttribute="trailing" id="FFb-eI-WhB"/> <constraint firstItem="RK9-ZZ-KNx" firstAttribute="centerY" secondItem="SQP-ML-8dW" secondAttribute="centerY" id="Glr-Qk-jDv"/> <constraint firstItem="I1W-Yg-7VA" firstAttribute="leading" secondItem="SQP-ML-8dW" secondAttribute="leading" constant="30" id="JdO-uB-Pg6"/> - <constraint firstItem="B9t-Fw-Xfq" firstAttribute="leading" secondItem="SQP-ML-8dW" secondAttribute="leading" id="JoY-h9-aCp"/> <constraint firstAttribute="bottom" secondItem="I1W-Yg-7VA" secondAttribute="bottom" id="LwS-F0-IaT"/> <constraint firstAttribute="height" constant="40" id="e48-qe-S93"/> <constraint firstAttribute="trailing" secondItem="RK9-ZZ-KNx" secondAttribute="trailing" constant="30" id="oa7-YE-qYE"/> <constraint firstItem="I1W-Yg-7VA" firstAttribute="centerY" secondItem="SQP-ML-8dW" secondAttribute="centerY" id="tOY-l3-6t4"/> - <constraint firstAttribute="trailing" secondItem="B9t-Fw-Xfq" secondAttribute="trailing" id="xeI-uE-TZl"/> </constraints> <variation key="default"> <mask key="constraints"> <exclude reference="6Kz-Cu-2H6"/> <exclude reference="LwS-F0-IaT"/> - <exclude reference="FFb-eI-WhB"/> </mask> </variation> <connections> @@ -1017,9 +995,6 @@ <nil key="textColor"/> <fontDescription key="fontDescription" name="PingFangSC-Regular" family="PingFang SC" pointSize="12"/> <textInputTraits key="textInputTraits"/> - <connections> - <outlet property="delegate" destination="96G-49-ueh" id="YL6-b9-2HH"/> - </connections> </textField> <button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Njp-Tr-7rt"> <rect key="frame" x="314" y="-0.5" width="40" height="40"/> @@ -1199,7 +1174,6 @@ <outlet property="lbPhone" destination="XAZ-es-XbK" id="3xN-ic-WmI"/> <outlet property="lbShippingRate" destination="pVN-aG-lfu" id="YuB-rr-DOP"/> <outlet property="lbTotalPrice" destination="fdr-W0-QCc" id="Cfi-P2-B3O"/> - <outlet property="marginTopContent" destination="58G-Ar-blr" id="0hg-Y4-Ske"/> <outlet property="submit" destination="vT5-Az-K57" id="fwS-UU-AZ4"/> <outlet property="tfDiscount" destination="O0I-6i-BPd" id="d3J-D9-wvt"/> <outlet property="vAddressHeight" destination="zO1-RN-x44" id="VIC-wQ-AuJ"/> diff --git a/iCemarose/Class/View/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.h b/iCemarose/Class/View/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.h new file mode 100644 index 0000000..fbd8619 --- /dev/null +++ b/iCemarose/Class/View/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.h @@ -0,0 +1,15 @@ +// +// TPKeyboardAvoidingCollectionView.h +// TPKeyboardAvoiding +// +// Created by Michael Tyson on 30/09/2013. +// Copyright 2015 A Tasty Pixel & The CocoaBots. All rights reserved. +// + +#import <UIKit/UIKit.h> +#import "UIScrollView+TPKeyboardAvoidingAdditions.h" + +@interface TPKeyboardAvoidingCollectionView : UICollectionView <UITextFieldDelegate, UITextViewDelegate> +- (BOOL)focusNextTextField; +- (void)scrollToActiveTextField; +@end diff --git a/iCemarose/Class/View/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.m b/iCemarose/Class/View/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.m new file mode 100644 index 0000000..2475512 --- /dev/null +++ b/iCemarose/Class/View/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.m @@ -0,0 +1,113 @@ +// +// TPKeyboardAvoidingCollectionView.m +// TPKeyboardAvoiding +// +// Created by Michael Tyson on 30/09/2013. +// Copyright 2015 A Tasty Pixel & The CocoaBots. All rights reserved. +// + +#import "TPKeyboardAvoidingCollectionView.h" + +@interface TPKeyboardAvoidingCollectionView () <UITextFieldDelegate, UITextViewDelegate> +@end + +@implementation TPKeyboardAvoidingCollectionView + +#pragma mark - Setup/Teardown + +- (void)setup { + if ( [self hasAutomaticKeyboardAvoidingBehaviour] ) return; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillShow:) name:UIKeyboardWillChangeFrameNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToActiveTextField) name:UITextViewTextDidBeginEditingNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToActiveTextField) name:UITextFieldTextDidBeginEditingNotification object:nil]; +} + +-(id)initWithFrame:(CGRect)frame { + if ( !(self = [super initWithFrame:frame]) ) return nil; + [self setup]; + return self; +} + +- (id)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout { + if ( !(self = [super initWithFrame:frame collectionViewLayout:layout]) ) return nil; + [self setup]; + return self; +} + +-(void)awakeFromNib { + [super awakeFromNib]; + [self setup]; +} + +-(void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +#if !__has_feature(objc_arc) + [super dealloc]; +#endif +} + + +-(BOOL)hasAutomaticKeyboardAvoidingBehaviour { + if ( [[[UIDevice currentDevice] systemVersion] integerValue] >= 9 + && [self.delegate isKindOfClass:[UICollectionViewController class]] ) { + // Theory: It looks like iOS 9's collection views automatically avoid the keyboard. As usual + // Apple have totally failed to document this anywhere, so this is just a guess. + return YES; + } + + return NO; +} + +-(void)setFrame:(CGRect)frame { + [super setFrame:frame]; + [self TPKeyboardAvoiding_updateContentInset]; +} + +-(void)setContentSize:(CGSize)contentSize { + if (CGSizeEqualToSize(contentSize, self.contentSize)) { + // Prevent triggering contentSize when it's already the same that + // cause weird infinte scrolling and locking bug + return; + } + [super setContentSize:contentSize]; + [self TPKeyboardAvoiding_updateContentInset]; +} + +- (BOOL)focusNextTextField { + return [self TPKeyboardAvoiding_focusNextTextField]; + +} +- (void)scrollToActiveTextField { + return [self TPKeyboardAvoiding_scrollToActiveTextField]; +} + +#pragma mark - Responders, events + +-(void)willMoveToSuperview:(UIView *)newSuperview { + [super willMoveToSuperview:newSuperview]; + if ( !newSuperview ) { + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) object:self]; + } +} + +- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + [[self TPKeyboardAvoiding_findFirstResponderBeneathView:self] resignFirstResponder]; + [super touchesEnded:touches withEvent:event]; +} + +-(BOOL)textFieldShouldReturn:(UITextField *)textField { + if ( ![self focusNextTextField] ) { + [textField resignFirstResponder]; + } + return YES; +} + +-(void)layoutSubviews { + [super layoutSubviews]; + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) object:self]; + [self performSelector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) withObject:self afterDelay:0.1]; +} + +@end diff --git a/iCemarose/Class/View/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.h b/iCemarose/Class/View/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.h new file mode 100755 index 0000000..6947992 --- /dev/null +++ b/iCemarose/Class/View/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.h @@ -0,0 +1,16 @@ +// +// TPKeyboardAvoidingScrollView.h +// TPKeyboardAvoiding +// +// Created by Michael Tyson on 30/09/2013. +// Copyright 2015 A Tasty Pixel. All rights reserved. +// + +#import <UIKit/UIKit.h> +#import "UIScrollView+TPKeyboardAvoidingAdditions.h" + +@interface TPKeyboardAvoidingScrollView : UIScrollView <UITextFieldDelegate, UITextViewDelegate> +- (void)contentSizeToFit; +- (BOOL)focusNextTextField; +- (void)scrollToActiveTextField; +@end diff --git a/iCemarose/Class/View/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.m b/iCemarose/Class/View/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.m new file mode 100644 index 0000000..e811391 --- /dev/null +++ b/iCemarose/Class/View/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.m @@ -0,0 +1,92 @@ +// +// TPKeyboardAvoidingScrollView.m +// TPKeyboardAvoiding +// +// Created by Michael Tyson on 30/09/2013. +// Copyright 2015 A Tasty Pixel. All rights reserved. +// + +#import "TPKeyboardAvoidingScrollView.h" + +@interface TPKeyboardAvoidingScrollView () <UITextFieldDelegate, UITextViewDelegate> +@end + +@implementation TPKeyboardAvoidingScrollView + +#pragma mark - Setup/Teardown + +- (void)setup { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillShow:) name:UIKeyboardWillChangeFrameNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToActiveTextField) name:UITextViewTextDidBeginEditingNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToActiveTextField) name:UITextFieldTextDidBeginEditingNotification object:nil]; +} + +-(id)initWithFrame:(CGRect)frame { + if ( !(self = [super initWithFrame:frame]) ) return nil; + [self setup]; + return self; +} + +-(void)awakeFromNib { + [super awakeFromNib]; + [self setup]; +} + +-(void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +#if !__has_feature(objc_arc) + [super dealloc]; +#endif +} + +-(void)setFrame:(CGRect)frame { + [super setFrame:frame]; + [self TPKeyboardAvoiding_updateContentInset]; +} + +-(void)setContentSize:(CGSize)contentSize { + [super setContentSize:contentSize]; + [self TPKeyboardAvoiding_updateFromContentSizeChange]; +} + +- (void)contentSizeToFit { + self.contentSize = [self TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames]; +} + +- (BOOL)focusNextTextField { + return [self TPKeyboardAvoiding_focusNextTextField]; + +} +- (void)scrollToActiveTextField { + return [self TPKeyboardAvoiding_scrollToActiveTextField]; +} + +#pragma mark - Responders, events + +-(void)willMoveToSuperview:(UIView *)newSuperview { + [super willMoveToSuperview:newSuperview]; + if ( !newSuperview ) { + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) object:self]; + } +} + +- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + [[self TPKeyboardAvoiding_findFirstResponderBeneathView:self] resignFirstResponder]; + [super touchesEnded:touches withEvent:event]; +} + +-(BOOL)textFieldShouldReturn:(UITextField *)textField { + if ( ![self focusNextTextField] ) { + [textField resignFirstResponder]; + } + return YES; +} + +-(void)layoutSubviews { + [super layoutSubviews]; + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) object:self]; + [self performSelector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) withObject:self afterDelay:0.1]; +} + +@end diff --git a/iCemarose/Class/View/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.h b/iCemarose/Class/View/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.h new file mode 100644 index 0000000..7e05a0e --- /dev/null +++ b/iCemarose/Class/View/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.h @@ -0,0 +1,15 @@ +// +// TPKeyboardAvoidingTableView.h +// TPKeyboardAvoiding +// +// Created by Michael Tyson on 30/09/2013. +// Copyright 2015 A Tasty Pixel. All rights reserved. +// + +#import <UIKit/UIKit.h> +#import "UIScrollView+TPKeyboardAvoidingAdditions.h" + +@interface TPKeyboardAvoidingTableView : UITableView <UITextFieldDelegate, UITextViewDelegate> +- (BOOL)focusNextTextField; +- (void)scrollToActiveTextField; +@end diff --git a/iCemarose/Class/View/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.m b/iCemarose/Class/View/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.m new file mode 100644 index 0000000..7eefa23 --- /dev/null +++ b/iCemarose/Class/View/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.m @@ -0,0 +1,117 @@ +// +// TPKeyboardAvoidingTableView.m +// TPKeyboardAvoiding +// +// Created by Michael Tyson on 30/09/2013. +// Copyright 2015 A Tasty Pixel. All rights reserved. +// + +#import "TPKeyboardAvoidingTableView.h" + +@interface TPKeyboardAvoidingTableView () <UITextFieldDelegate, UITextViewDelegate> +@end + +@implementation TPKeyboardAvoidingTableView + +#pragma mark - Setup/Teardown + +- (void)setup { + if ( [self hasAutomaticKeyboardAvoidingBehaviour] ) return; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillShow:) name:UIKeyboardWillChangeFrameNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToActiveTextField) name:UITextViewTextDidBeginEditingNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToActiveTextField) name:UITextFieldTextDidBeginEditingNotification object:nil]; +} + +-(id)initWithFrame:(CGRect)frame { + if ( !(self = [super initWithFrame:frame]) ) return nil; + [self setup]; + return self; +} + +-(id)initWithFrame:(CGRect)frame style:(UITableViewStyle)withStyle { + if ( !(self = [super initWithFrame:frame style:withStyle]) ) return nil; + [self setup]; + return self; +} + +-(void)awakeFromNib { + [super awakeFromNib]; + [self setup]; +} + +-(void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +#if !__has_feature(objc_arc) + [super dealloc]; +#endif +} + +-(BOOL)hasAutomaticKeyboardAvoidingBehaviour { + if ( [self.delegate isKindOfClass:[UITableViewController class]] ) { + // Theory: Apps built using the iOS 8.3 SDK (probably: older SDKs not tested) seem to handle keyboard + // avoiding automatically with UITableViewController. This doesn't seem to be documented anywhere + // by Apple, so results obtained only empirically. + return YES; + } + + return NO; +} + +-(void)setFrame:(CGRect)frame { + [super setFrame:frame]; + if ( [self hasAutomaticKeyboardAvoidingBehaviour] ) return; + [self TPKeyboardAvoiding_updateContentInset]; +} + +-(void)setContentSize:(CGSize)contentSize { + if ( [self hasAutomaticKeyboardAvoidingBehaviour] ) { + [super setContentSize:contentSize]; + return; + } + if (CGSizeEqualToSize(contentSize, self.contentSize)) { + // Prevent triggering contentSize when it's already the same + // this cause table view to scroll to top on contentInset changes + return; + } + [super setContentSize:contentSize]; + [self TPKeyboardAvoiding_updateContentInset]; +} + +- (BOOL)focusNextTextField { + return [self TPKeyboardAvoiding_focusNextTextField]; + +} +- (void)scrollToActiveTextField { + return [self TPKeyboardAvoiding_scrollToActiveTextField]; +} + +#pragma mark - Responders, events + +-(void)willMoveToSuperview:(UIView *)newSuperview { + [super willMoveToSuperview:newSuperview]; + if ( !newSuperview ) { + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) object:self]; + } +} + +- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + [[self TPKeyboardAvoiding_findFirstResponderBeneathView:self] resignFirstResponder]; + [super touchesEnded:touches withEvent:event]; +} + +-(BOOL)textFieldShouldReturn:(UITextField *)textField { + if ( ![self focusNextTextField] ) { + [textField resignFirstResponder]; + } + return YES; +} + +-(void)layoutSubviews { + [super layoutSubviews]; + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) object:self]; + [self performSelector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) withObject:self afterDelay:0.1]; +} + +@end diff --git a/iCemarose/Class/View/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.h b/iCemarose/Class/View/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.h new file mode 100644 index 0000000..80b9b10 --- /dev/null +++ b/iCemarose/Class/View/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.h @@ -0,0 +1,22 @@ +// +// UIScrollView+TPKeyboardAvoidingAdditions.h +// TPKeyboardAvoiding +// +// Created by Michael Tyson on 30/09/2013. +// Copyright 2015 A Tasty Pixel. All rights reserved. +// + +#import <UIKit/UIKit.h> + +@interface UIScrollView (TPKeyboardAvoidingAdditions) +- (BOOL)TPKeyboardAvoiding_focusNextTextField; +- (void)TPKeyboardAvoiding_scrollToActiveTextField; + +- (void)TPKeyboardAvoiding_keyboardWillShow:(NSNotification*)notification; +- (void)TPKeyboardAvoiding_keyboardWillHide:(NSNotification*)notification; +- (void)TPKeyboardAvoiding_updateContentInset; +- (void)TPKeyboardAvoiding_updateFromContentSizeChange; +- (void)TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:(UIView*)view; +- (UIView*)TPKeyboardAvoiding_findFirstResponderBeneathView:(UIView*)view; +-(CGSize)TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames; +@end diff --git a/iCemarose/Class/View/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.m b/iCemarose/Class/View/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.m new file mode 100644 index 0000000..3c9dafb --- /dev/null +++ b/iCemarose/Class/View/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.m @@ -0,0 +1,443 @@ +// +// UIScrollView+TPKeyboardAvoidingAdditions.m +// TPKeyboardAvoiding +// +// Created by Michael Tyson on 30/09/2013. +// Copyright 2015 A Tasty Pixel. All rights reserved. +// + +#import "UIScrollView+TPKeyboardAvoidingAdditions.h" +#import "TPKeyboardAvoidingScrollView.h" +#import <objc/runtime.h> + +static const CGFloat kCalculatedContentPadding = 10; +static const CGFloat kMinimumScrollOffsetPadding = 20; + +static NSString * const kUIKeyboardAnimationDurationUserInfoKey = @"UIKeyboardAnimationDurationUserInfoKey"; + +static const int kStateKey; + +#define _UIKeyboardFrameEndUserInfoKey (&UIKeyboardFrameEndUserInfoKey != NULL ? UIKeyboardFrameEndUserInfoKey : @"UIKeyboardBoundsUserInfoKey") + +@interface TPKeyboardAvoidingState : NSObject +@property (nonatomic, assign) UIEdgeInsets priorInset; +@property (nonatomic, assign) UIEdgeInsets priorScrollIndicatorInsets; +@property (nonatomic, assign) BOOL keyboardVisible; +@property (nonatomic, assign) CGRect keyboardRect; +@property (nonatomic, assign) CGSize priorContentSize; +@property (nonatomic, assign) BOOL priorPagingEnabled; +@property (nonatomic, assign) BOOL ignoringNotifications; +@property (nonatomic, assign) BOOL keyboardAnimationInProgress; +@property (nonatomic, assign) CGFloat animationDuration; +@end + +@implementation UIScrollView (TPKeyboardAvoidingAdditions) + +- (TPKeyboardAvoidingState*)keyboardAvoidingState { + TPKeyboardAvoidingState *state = objc_getAssociatedObject(self, &kStateKey); + if ( !state ) { + state = [[TPKeyboardAvoidingState alloc] init]; + objc_setAssociatedObject(self, &kStateKey, state, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +#if !__has_feature(objc_arc) + [state release]; +#endif + } + return state; +} + +- (void)TPKeyboardAvoiding_keyboardWillShow:(NSNotification*)notification { + NSDictionary *info = [notification userInfo]; + TPKeyboardAvoidingState *state = self.keyboardAvoidingState; + + state.animationDuration = [[info objectForKey:kUIKeyboardAnimationDurationUserInfoKey] doubleValue]; + + CGRect keyboardRect = [self convertRect:[[info objectForKey:_UIKeyboardFrameEndUserInfoKey] CGRectValue] fromView:nil]; + if (CGRectIsEmpty(keyboardRect)) { + return; + } + + if ( state.ignoringNotifications ) { + return; + } + + state.keyboardRect = keyboardRect; + + if ( !state.keyboardVisible ) { + state.priorInset = self.contentInset; + state.priorScrollIndicatorInsets = self.scrollIndicatorInsets; + state.priorPagingEnabled = self.pagingEnabled; + } + + state.keyboardVisible = YES; + self.pagingEnabled = NO; + + if ( [self isKindOfClass:[TPKeyboardAvoidingScrollView class]] ) { + state.priorContentSize = self.contentSize; + + if ( CGSizeEqualToSize(self.contentSize, CGSizeZero) ) { + // Set the content size, if it's not set. Do not set content size explicitly if auto-layout + // is being used to manage subviews + self.contentSize = [self TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames]; + } + } + + // Delay until a future run loop such that the cursor position is available in a text view + // In other words, it's not available (specifically, the prior cursor position is returned) when the first keyboard position change notification fires + // NOTE: Unfortunately, using dispatch_async(main_queue) did not result in a sufficient-enough delay + // for the text view's current cursor position to be available + dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)); + dispatch_after(delay, dispatch_get_main_queue(), ^{ + + // Shrink view's inset by the keyboard's height, and scroll to show the text field/view being edited + [UIView beginAnimations:nil context:NULL]; + + [UIView setAnimationDelegate:self]; + [UIView setAnimationWillStartSelector:@selector(keyboardViewAppear:context:)]; + [UIView setAnimationDidStopSelector:@selector(keyboardViewDisappear:finished:context:)]; + + [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]]; + [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]]; + + UIView *firstResponder = [self TPKeyboardAvoiding_findFirstResponderBeneathView:self]; + if ( firstResponder ) { + + self.contentInset = [self TPKeyboardAvoiding_contentInsetForKeyboard]; + + CGFloat viewableHeight = self.bounds.size.height - self.contentInset.top - self.contentInset.bottom; + [self setContentOffset:CGPointMake(self.contentOffset.x, + [self TPKeyboardAvoiding_idealOffsetForView:firstResponder + withViewingAreaHeight:viewableHeight]) + animated:NO]; + } + + self.scrollIndicatorInsets = self.contentInset; + [self layoutIfNeeded]; + + [UIView commitAnimations]; + }); +} + +- (void)keyboardViewAppear:(NSString *)animationID context:(void *)context { + self.keyboardAvoidingState.keyboardAnimationInProgress = true; +} + +- (void)keyboardViewDisappear:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context { + if (finished.boolValue) { + self.keyboardAvoidingState.keyboardAnimationInProgress = false; + } +} + +- (void)TPKeyboardAvoiding_keyboardWillHide:(NSNotification*)notification { + CGRect keyboardRect = [self convertRect:[[[notification userInfo] objectForKey:_UIKeyboardFrameEndUserInfoKey] CGRectValue] fromView:nil]; + if (CGRectIsEmpty(keyboardRect) && !self.keyboardAvoidingState.keyboardAnimationInProgress) { + return; + } + + TPKeyboardAvoidingState *state = self.keyboardAvoidingState; + + if ( state.ignoringNotifications ) { + return; + } + + if ( !state.keyboardVisible ) { + return; + } + + state.keyboardRect = CGRectZero; + state.keyboardVisible = NO; + + // Restore dimensions to prior size + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]]; + [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]]; + + if ( [self isKindOfClass:[TPKeyboardAvoidingScrollView class]] ) { + self.contentSize = state.priorContentSize; + } + + self.contentInset = state.priorInset; + self.scrollIndicatorInsets = state.priorScrollIndicatorInsets; + self.pagingEnabled = state.priorPagingEnabled; + [self layoutIfNeeded]; + [UIView commitAnimations]; +} + +- (void)TPKeyboardAvoiding_updateContentInset { + TPKeyboardAvoidingState *state = self.keyboardAvoidingState; + if ( state.keyboardVisible ) { + self.contentInset = [self TPKeyboardAvoiding_contentInsetForKeyboard]; + } +} + +- (void)TPKeyboardAvoiding_updateFromContentSizeChange { + TPKeyboardAvoidingState *state = self.keyboardAvoidingState; + if ( state.keyboardVisible ) { + state.priorContentSize = self.contentSize; + self.contentInset = [self TPKeyboardAvoiding_contentInsetForKeyboard]; + } +} + +#pragma mark - Utilities + +- (BOOL)TPKeyboardAvoiding_focusNextTextField { + UIView *firstResponder = [self TPKeyboardAvoiding_findFirstResponderBeneathView:self]; + if ( !firstResponder ) { + return NO; + } + + UIView *view = [self TPKeyboardAvoiding_findNextInputViewAfterView:firstResponder beneathView:self]; + + if ( view ) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0), dispatch_get_main_queue(), ^{ + TPKeyboardAvoidingState *state = self.keyboardAvoidingState; + state.ignoringNotifications = YES; + [view becomeFirstResponder]; + state.ignoringNotifications = NO; + }); + return YES; + } + + return NO; +} + +-(void)TPKeyboardAvoiding_scrollToActiveTextField { + TPKeyboardAvoidingState *state = self.keyboardAvoidingState; + + if ( !state.keyboardVisible ) return; + + UIView *firstResponder = [self TPKeyboardAvoiding_findFirstResponderBeneathView:self]; + if ( !firstResponder ) { + return; + } + // Ignore any keyboard notification that occur while we scroll + // (seems to be an iOS 9 bug that causes jumping text in UITextField) + state.ignoringNotifications = YES; + + CGFloat visibleSpace = self.bounds.size.height - self.contentInset.top - self.contentInset.bottom; + + CGPoint idealOffset + = CGPointMake(self.contentOffset.x, + [self TPKeyboardAvoiding_idealOffsetForView:firstResponder + withViewingAreaHeight:visibleSpace]); + + // Ordinarily we'd use -setContentOffset:animated:YES here, but it interferes with UIScrollView + // behavior which automatically ensures that the first responder is within its bounds + [UIView animateWithDuration:state.animationDuration animations:^{ + self.contentOffset = idealOffset; + } completion:^(BOOL finished) { + state.ignoringNotifications = NO; + }]; +} + +#pragma mark - Helpers + +- (UIView*)TPKeyboardAvoiding_findFirstResponderBeneathView:(UIView*)view { + // Search recursively for first responder + for ( UIView *childView in view.subviews ) { + if ( [childView respondsToSelector:@selector(isFirstResponder)] && [childView isFirstResponder] ) return childView; + UIView *result = [self TPKeyboardAvoiding_findFirstResponderBeneathView:childView]; + if ( result ) return result; + } + return nil; +} + +- (UIView*)TPKeyboardAvoiding_findNextInputViewAfterView:(UIView*)priorView beneathView:(UIView*)view { + UIView * candidate = nil; + [self TPKeyboardAvoiding_findNextInputViewAfterView:priorView beneathView:view bestCandidate:&candidate]; + return candidate; +} + +- (void)TPKeyboardAvoiding_findNextInputViewAfterView:(UIView*)priorView beneathView:(UIView*)view bestCandidate:(UIView**)bestCandidate { + // Search recursively for input view below/to right of priorTextField + CGRect priorFrame = [self convertRect:priorView.frame fromView:priorView.superview]; + CGRect candidateFrame = *bestCandidate ? [self convertRect:(*bestCandidate).frame fromView:(*bestCandidate).superview] : CGRectZero; + CGFloat bestCandidateHeuristic = [self TPKeyboardAvoiding_nextInputViewHeuristicForViewFrame:candidateFrame]; + + for ( UIView *childView in view.subviews ) { + if ( [self TPKeyboardAvoiding_viewIsValidKeyViewCandidate:childView] ) { + CGRect frame = [self convertRect:childView.frame fromView:view]; + + // Use a heuristic to evaluate candidates + CGFloat heuristic = [self TPKeyboardAvoiding_nextInputViewHeuristicForViewFrame:frame]; + + // Find views beneath, or to the right. For those views that match, choose the view closest to the top left + if ( childView != priorView + && ((fabs(CGRectGetMinY(frame) - CGRectGetMinY(priorFrame)) < FLT_EPSILON && CGRectGetMinX(frame) > CGRectGetMinX(priorFrame)) + || CGRectGetMinY(frame) > CGRectGetMinY(priorFrame)) + && (!*bestCandidate || heuristic > bestCandidateHeuristic) ) { + + *bestCandidate = childView; + bestCandidateHeuristic = heuristic; + } + } else { + [self TPKeyboardAvoiding_findNextInputViewAfterView:priorView beneathView:childView bestCandidate:bestCandidate]; + } + } +} + +- (CGFloat)TPKeyboardAvoiding_nextInputViewHeuristicForViewFrame:(CGRect)frame { + return (-frame.origin.y * 1000.0) // Prefer elements closest to top (most important) + + (-frame.origin.x); // Prefer elements closest to left +} + +- (BOOL)TPKeyboardAvoiding_viewHiddenOrUserInteractionNotEnabled:(UIView *)view { + while ( view ) { + if ( view.hidden || !view.userInteractionEnabled ) { + return YES; + } + view = view.superview; + } + return NO; +} + +- (BOOL)TPKeyboardAvoiding_viewIsValidKeyViewCandidate:(UIView *)view { + if ( [self TPKeyboardAvoiding_viewHiddenOrUserInteractionNotEnabled:view] ) return NO; + + if ( [view isKindOfClass:[UITextField class]] && ((UITextField*)view).enabled ) { + return YES; + } + + if ( [view isKindOfClass:[UITextView class]] && ((UITextView*)view).isEditable ) { + return YES; + } + + return NO; +} + +- (void)TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:(UIView*)view { + for ( UIView *childView in view.subviews ) { + if ( ([childView isKindOfClass:[UITextField class]] || [childView isKindOfClass:[UITextView class]]) ) { + [self TPKeyboardAvoiding_initializeView:childView]; + } else { + [self TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:childView]; + } + } +} + +-(CGSize)TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames { + + BOOL wasShowingVerticalScrollIndicator = self.showsVerticalScrollIndicator; + BOOL wasShowingHorizontalScrollIndicator = self.showsHorizontalScrollIndicator; + + self.showsVerticalScrollIndicator = NO; + self.showsHorizontalScrollIndicator = NO; + + CGRect rect = CGRectZero; + for ( UIView *view in self.subviews ) { + rect = CGRectUnion(rect, view.frame); + } + rect.size.height += kCalculatedContentPadding; + + self.showsVerticalScrollIndicator = wasShowingVerticalScrollIndicator; + self.showsHorizontalScrollIndicator = wasShowingHorizontalScrollIndicator; + + return rect.size; +} + + +- (UIEdgeInsets)TPKeyboardAvoiding_contentInsetForKeyboard { + TPKeyboardAvoidingState *state = self.keyboardAvoidingState; + UIEdgeInsets newInset = self.contentInset; + CGRect keyboardRect = state.keyboardRect; + newInset.bottom = keyboardRect.size.height - MAX((CGRectGetMaxY(keyboardRect) - CGRectGetMaxY(self.bounds)), 0); + return newInset; +} + +-(CGFloat)TPKeyboardAvoiding_idealOffsetForView:(UIView *)view withViewingAreaHeight:(CGFloat)viewAreaHeight { + CGSize contentSize = self.contentSize; + __block CGFloat offset = 0.0; + + CGRect subviewRect = [view convertRect:view.bounds toView:self]; + + __block CGFloat padding = 0.0; + __block UIEdgeInsets contentInset; + +#ifdef __IPHONE_11_0 + if (@available(iOS 11.0, *)) { + contentInset = self.adjustedContentInset; + } else { + contentInset = self.contentInset; + } +#else + contentInset = self.contentInset; +#endif + + void(^centerViewInViewableArea)(void) = ^ { + // Attempt to center the subview in the visible space + padding = (viewAreaHeight - subviewRect.size.height) / 2; + + // But if that means there will be less than kMinimumScrollOffsetPadding + // pixels above the view, then substitute kMinimumScrollOffsetPadding + if (padding < kMinimumScrollOffsetPadding ) { + padding = kMinimumScrollOffsetPadding; + } + + // Ideal offset places the subview rectangle origin "padding" points from the top of the scrollview. + // If there is a top contentInset, also compensate for this so that subviewRect will not be placed under + // things like navigation bars. + offset = subviewRect.origin.y - padding - contentInset.top; + }; + + // If possible, center the caret in the visible space. Otherwise, center the entire view in the visible space. + if ([view conformsToProtocol:@protocol(UITextInput)]) { + UIView <UITextInput> *textInput = (UIView <UITextInput>*)view; + UITextPosition *caretPosition = [textInput selectedTextRange].start; + if (caretPosition) { + CGRect caretRect = [self convertRect:[textInput caretRectForPosition:caretPosition] fromView:textInput]; + + // Attempt to center the cursor in the visible space + // pixels above the view, then substitute kMinimumScrollOffsetPadding + padding = (viewAreaHeight - caretRect.size.height) / 2; + + // But if that means there will be less than kMinimumScrollOffsetPadding + // pixels above the view, then substitute kMinimumScrollOffsetPadding + if (padding < kMinimumScrollOffsetPadding ) { + padding = kMinimumScrollOffsetPadding; + } + + // Ideal offset places the subview rectangle origin "padding" points from the top of the scrollview. + // If there is a top contentInset, also compensate for this so that subviewRect will not be placed under + // things like navigation bars. + offset = caretRect.origin.y - padding - contentInset.top; + } else { + centerViewInViewableArea(); + } + } else { + centerViewInViewableArea(); + } + + // Constrain the new contentOffset so we can't scroll past the bottom. Note that we don't take the bottom + // inset into account, as this is manipulated to make space for the keyboard. + CGFloat maxOffset = contentSize.height - viewAreaHeight - contentInset.top; + if (offset > maxOffset) { + offset = maxOffset; + } + + // Constrain the new contentOffset so we can't scroll past the top, taking contentInsets into account + if ( offset < -contentInset.top ) { + offset = -contentInset.top; + } + + return offset; +} + +- (void)TPKeyboardAvoiding_initializeView:(UIView*)view { + if ( [view isKindOfClass:[UITextField class]] + && (((UITextField*)view).returnKeyType == UIReturnKeyDefault || (((UITextField*)view).returnKeyType == UIReturnKeyNext)) + && (![(UITextField*)view delegate] || [(UITextField*)view delegate] == (id<UITextFieldDelegate>)self) ) { + [(UITextField*)view setDelegate:(id<UITextFieldDelegate>)self]; + UIView *otherView = [self TPKeyboardAvoiding_findNextInputViewAfterView:view beneathView:self]; + + if ( otherView ) { + ((UITextField*)view).returnKeyType = UIReturnKeyNext; + } else { + ((UITextField*)view).returnKeyType = UIReturnKeyDone; + } + } +} + +@end + + +@implementation TPKeyboardAvoidingState +@end diff --git a/iCemarose/Header-Prefix.h b/iCemarose/Header-Prefix.h index 134ddf9..f51f611 100644 --- a/iCemarose/Header-Prefix.h +++ b/iCemarose/Header-Prefix.h @@ -58,6 +58,8 @@ #define NO_MORE_DATA @"------ 沒有啦 ------" +#define Order_API_Auth @"Basic YzJmNmZhZTk3NzQxZWE2ZGI0Y2FkN2FlOGY3MGZlZjM==" + //正式的微信key #define WechatAppKey @"wx355a497b2a2dd6d5"