Commit 18b81387 by houweibin

1,软键盘挡住优惠码输入框问题

2,去掉多余的线
3,其他调整
parent 70bc6c29
No related merge requests found
......@@ -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 */,
......
......@@ -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
......
......@@ -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;
......
......@@ -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;
......
......@@ -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:@"未成功初始化订单"];
......
......@@ -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"/>
......
//
// 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
//
// 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
//
// 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
//
// 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
//
// 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
//
// 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
//
// 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
//
// 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
......@@ -58,6 +58,8 @@
#define NO_MORE_DATA @"------ 沒有啦 ------"
#define Order_API_Auth @"Basic YzJmNmZhZTk3NzQxZWE2ZGI0Y2FkN2FlOGY3MGZlZjM=="
//正式的微信key
#define WechatAppKey @"wx355a497b2a2dd6d5"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment