mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 11:08:06 +00:00
Wizard: add TPKeyboardAvoiding framework and use it to remove frame resizing code
This commit is contained in:
parent
009bb78e7c
commit
a764686db3
16 changed files with 720 additions and 176 deletions
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="4514" systemVersion="13B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<deployment defaultVersion="1072" identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3747"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="WizardViewController">
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
<rect key="frame" x="0.0" y="0.0" width="320" height="460"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" tag="1" contentMode="scaleToFill" bounces="NO" showsHorizontalScrollIndicator="NO" id="98" userLabel="contentView">
|
||||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" tag="1" contentMode="scaleToFill" bounces="NO" showsHorizontalScrollIndicator="NO" id="98" userLabel="contentView" customClass="TPKeyboardAvoidingScrollView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="394"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
</scrollView>
|
||||
|
|
@ -97,6 +97,8 @@
|
|||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
|
|
@ -109,4 +111,9 @@
|
|||
<image name="setup_start_default.png" width="320" height="154"/>
|
||||
<image name="setup_start_over.png" width="320" height="154"/>
|
||||
</resources>
|
||||
</document>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
<simulatedScreenMetrics key="destination" type="retina4"/>
|
||||
</simulatedMetricsContainer>
|
||||
</document>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="5056" systemVersion="13C1021" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<deployment defaultVersion="1536" identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3733"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="WizardViewController">
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
<rect key="frame" x="0.0" y="0.0" width="768" height="1024"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" tag="1" contentMode="scaleToFill" bounces="NO" showsHorizontalScrollIndicator="NO" id="98" userLabel="contentView">
|
||||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" tag="1" contentMode="scaleToFill" bounces="NO" showsHorizontalScrollIndicator="NO" id="98" userLabel="contentView" customClass="TPKeyboardAvoidingScrollView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="768" height="966"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
</scrollView>
|
||||
|
|
@ -98,12 +98,14 @@
|
|||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" id="118" userLabel="Landscape View">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" tag="1" contentMode="scaleToFill" bounces="NO" showsHorizontalScrollIndicator="NO" id="119" userLabel="contentView">
|
||||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" tag="1" contentMode="scaleToFill" bounces="NO" showsHorizontalScrollIndicator="NO" id="119" userLabel="contentView" customClass="TPKeyboardAvoidingScrollView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1024" height="711"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
</scrollView>
|
||||
|
|
@ -180,6 +182,8 @@
|
|||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
|
|
@ -200,4 +204,9 @@
|
|||
<image name="setup_start_over.png" width="320" height="154"/>
|
||||
<image name="setup_start_over_landscape.png" width="1024" height="171"/>
|
||||
</resources>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
<simulatedScreenMetrics key="destination" type="retina4"/>
|
||||
</simulatedMetricsContainer>
|
||||
</document>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6751" systemVersion="14B25" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6736"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="WizardViewController">
|
||||
|
|
@ -22,7 +22,6 @@
|
|||
<outlet property="provisionedDomain" destination="wRB-Sh-K8J" id="Ieb-x8-yL4"/>
|
||||
<outlet property="provisionedPassword" destination="ClH-fT-a8N" id="h61-p1-4qG"/>
|
||||
<outlet property="provisionedUsername" destination="MyR-eX-QTa" id="gmr-FI-hpH"/>
|
||||
<outlet property="purchaseButton" destination="uIp-br-8Kv" id="Ov2-V4-LLx"/>
|
||||
<outlet property="registerButton" destination="77" id="A9h-Es-kxv"/>
|
||||
<outlet property="remoteProvisioningButton" destination="Kbn-dL-C5h" id="PPk-DJ-nEb"/>
|
||||
<outlet property="transportChooser" destination="Nrv-SM-lMf" id="7iR-aG-eQf"/>
|
||||
|
|
@ -244,22 +243,6 @@
|
|||
<action selector="onRegisterClick:" destination="-1" eventType="touchUpInside" id="113"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="uIp-br-8Kv" userLabel="purchaseButton" customClass="UILinphoneButton">
|
||||
<rect key="frame" x="33" y="481" width="255" height="73"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Purchase"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="20"/>
|
||||
<state key="normal" title="Purchase" backgroundImage="button_background_default.png">
|
||||
<color key="titleColor" red="0.35686274509999999" green="0.39607843139999999" blue="0.43529411759999997" alpha="1" colorSpace="deviceRGB"/>
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<state key="highlighted" backgroundImage="button_background_over.png">
|
||||
<color key="titleColor" red="0.72549019609999998" green="0.76862745099999996" blue="0.79607843140000001" alpha="1" colorSpace="deviceRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="onPurchaseAccountClick:" destination="-1" eventType="touchUpInside" id="BR1-hP-14E"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<point key="canvasLocation" x="927" y="295"/>
|
||||
|
|
|
|||
|
|
@ -44,9 +44,8 @@
|
|||
|
||||
- (instancetype)init {
|
||||
if ((self = [super init]) != nil) {
|
||||
_enabled =
|
||||
(([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) && ([SKPaymentQueue canMakePayments]) &&
|
||||
([[LinphoneManager instance] lpConfigBoolForKey:@"enabled" forSection:@"in_app_purchase"]));
|
||||
_enabled = (([SKPaymentQueue canMakePayments]) &&
|
||||
([[LinphoneManager instance] lpConfigBoolForKey:@"enabled" forSection:@"in_app_purchase"]));
|
||||
_initialized = false;
|
||||
_available = false;
|
||||
_accountActivationInProgress = false;
|
||||
|
|
|
|||
20
Classes/Utils/TPKeyboardAvoiding/LICENSE.txt
Executable file
20
Classes/Utils/TPKeyboardAvoiding/LICENSE.txt
Executable file
|
|
@ -0,0 +1,20 @@
|
|||
Copyright (c) 2013 Michael Tyson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
14
Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.h
Executable file
14
Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.h
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// TPKeyboardAvoidingCollectionView.h
|
||||
//
|
||||
// Created by Michael Tyson on 30/09/2013.
|
||||
// Copyright 2013 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
|
||||
96
Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.m
Executable file
96
Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.m
Executable file
|
|
@ -0,0 +1,96 @@
|
|||
//
|
||||
// TPKeyboardAvoidingCollectionView.m
|
||||
//
|
||||
// Created by Michael Tyson on 30/09/2013.
|
||||
// Copyright 2013 A Tasty Pixel & The CocoaBots. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TPKeyboardAvoidingCollectionView.h"
|
||||
|
||||
@interface TPKeyboardAvoidingCollectionView () <UITextFieldDelegate, UITextViewDelegate>
|
||||
@end
|
||||
|
||||
@implementation TPKeyboardAvoidingCollectionView
|
||||
|
||||
#pragma mark - Setup/Teardown
|
||||
|
||||
- (void)setup {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillHide:) name:UIKeyboardWillHideNotification 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 {
|
||||
[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 {
|
||||
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) 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)textFieldDidBeginEditing:(UITextField *)textField {
|
||||
[self scrollToActiveTextField];
|
||||
}
|
||||
|
||||
-(void)textViewDidBeginEditing:(UITextView *)textView {
|
||||
[self scrollToActiveTextField];
|
||||
}
|
||||
|
||||
-(void)layoutSubviews {
|
||||
[super layoutSubviews];
|
||||
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) object:self];
|
||||
[self performSelector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) withObject:self afterDelay:0.1];
|
||||
}
|
||||
|
||||
@end
|
||||
15
Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.h
Executable file
15
Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.h
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// TPKeyboardAvoidingScrollView.h
|
||||
//
|
||||
// Created by Michael Tyson on 30/09/2013.
|
||||
// Copyright 2013 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
|
||||
89
Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.m
Executable file
89
Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.m
Executable file
|
|
@ -0,0 +1,89 @@
|
|||
//
|
||||
// TPKeyboardAvoidingScrollView.m
|
||||
//
|
||||
// Created by Michael Tyson on 30/09/2013.
|
||||
// Copyright 2013 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:UIKeyboardWillShowNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
|
||||
}
|
||||
|
||||
-(id)initWithFrame:(CGRect)frame {
|
||||
if ( !(self = [super initWithFrame:frame]) ) return nil;
|
||||
[self setup];
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)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) 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)textFieldDidBeginEditing:(UITextField *)textField {
|
||||
[self scrollToActiveTextField];
|
||||
}
|
||||
|
||||
-(void)textViewDidBeginEditing:(UITextView *)textView {
|
||||
[self scrollToActiveTextField];
|
||||
}
|
||||
|
||||
-(void)layoutSubviews {
|
||||
[super layoutSubviews];
|
||||
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) object:self];
|
||||
[self performSelector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) withObject:self afterDelay:0.1];
|
||||
}
|
||||
|
||||
@end
|
||||
14
Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.h
Executable file
14
Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.h
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// TPKeyboardAvoidingTableView.h
|
||||
//
|
||||
// Created by Michael Tyson on 30/09/2013.
|
||||
// Copyright 2013 A Tasty Pixel. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "UIScrollView+TPKeyboardAvoidingAdditions.h"
|
||||
|
||||
@interface TPKeyboardAvoidingTableView : UITableView <UITextFieldDelegate, UITextViewDelegate>
|
||||
- (BOOL)focusNextTextField;
|
||||
- (void)scrollToActiveTextField;
|
||||
@end
|
||||
91
Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.m
Executable file
91
Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.m
Executable file
|
|
@ -0,0 +1,91 @@
|
|||
//
|
||||
// TPKeyboardAvoidingTableView.m
|
||||
//
|
||||
// Created by Michael Tyson on 30/09/2013.
|
||||
// Copyright 2013 A Tasty Pixel. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TPKeyboardAvoidingTableView.h"
|
||||
|
||||
@interface TPKeyboardAvoidingTableView () <UITextFieldDelegate, UITextViewDelegate>
|
||||
@end
|
||||
|
||||
@implementation TPKeyboardAvoidingTableView
|
||||
|
||||
#pragma mark - Setup/Teardown
|
||||
|
||||
- (void)setup {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillHide:) name:UIKeyboardWillHideNotification 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 {
|
||||
[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_updateContentInset];
|
||||
}
|
||||
|
||||
- (BOOL)focusNextTextField {
|
||||
return [self TPKeyboardAvoiding_focusNextTextField];
|
||||
|
||||
}
|
||||
- (void)scrollToActiveTextField {
|
||||
return [self TPKeyboardAvoiding_scrollToActiveTextField];
|
||||
}
|
||||
|
||||
#pragma mark - Responders, events
|
||||
|
||||
- (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)textFieldDidBeginEditing:(UITextField *)textField {
|
||||
[self scrollToActiveTextField];
|
||||
}
|
||||
|
||||
-(void)textViewDidBeginEditing:(UITextView *)textView {
|
||||
[self scrollToActiveTextField];
|
||||
}
|
||||
|
||||
-(void)layoutSubviews {
|
||||
[super layoutSubviews];
|
||||
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) object:self];
|
||||
[self performSelector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) withObject:self afterDelay:0.1];
|
||||
}
|
||||
|
||||
@end
|
||||
22
Classes/Utils/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.h
Executable file
22
Classes/Utils/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.h
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// UIScrollView+TPKeyboardAvoidingAdditions.h
|
||||
// TPKeyboardAvoidingSample
|
||||
//
|
||||
// Created by Michael Tyson on 30/09/2013.
|
||||
// Copyright 2013 A Tasty Pixel. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.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
|
||||
285
Classes/Utils/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.m
Executable file
285
Classes/Utils/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.m
Executable file
|
|
@ -0,0 +1,285 @@
|
|||
//
|
||||
// UIScrollView+TPKeyboardAvoidingAdditions.m
|
||||
// TPKeyboardAvoidingSample
|
||||
//
|
||||
// Created by Michael Tyson on 30/09/2013.
|
||||
// Copyright 2013 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 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;
|
||||
@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 {
|
||||
TPKeyboardAvoidingState *state = self.keyboardAvoidingState;
|
||||
|
||||
if ( state.keyboardVisible ) {
|
||||
return;
|
||||
}
|
||||
|
||||
UIView *firstResponder = [self TPKeyboardAvoiding_findFirstResponderBeneathView:self];
|
||||
|
||||
state.keyboardRect = [self convertRect:[[[notification userInfo] objectForKey:_UIKeyboardFrameEndUserInfoKey] CGRectValue] fromView:nil];
|
||||
state.keyboardVisible = YES;
|
||||
state.priorInset = self.contentInset;
|
||||
state.priorScrollIndicatorInsets = self.scrollIndicatorInsets;
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
// 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 setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
|
||||
[UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]];
|
||||
|
||||
self.contentInset = [self TPKeyboardAvoiding_contentInsetForKeyboard];
|
||||
|
||||
if ( firstResponder ) {
|
||||
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;
|
||||
|
||||
[UIView commitAnimations];
|
||||
}
|
||||
|
||||
- (void)TPKeyboardAvoiding_keyboardWillHide:(NSNotification*)notification {
|
||||
TPKeyboardAvoidingState *state = self.keyboardAvoidingState;
|
||||
|
||||
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;
|
||||
[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;
|
||||
}
|
||||
|
||||
CGFloat minY = CGFLOAT_MAX;
|
||||
UIView *view = nil;
|
||||
[self TPKeyboardAvoiding_findTextFieldAfterTextField:firstResponder beneathView:self minY:&minY foundView:&view];
|
||||
|
||||
if ( view ) {
|
||||
[view performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0.0];
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(void)TPKeyboardAvoiding_scrollToActiveTextField {
|
||||
TPKeyboardAvoidingState *state = self.keyboardAvoidingState;
|
||||
|
||||
if ( !state.keyboardVisible ) return;
|
||||
|
||||
CGFloat visibleSpace = self.bounds.size.height - self.contentInset.top - self.contentInset.bottom;
|
||||
|
||||
CGPoint idealOffset = CGPointMake(0, [self TPKeyboardAvoiding_idealOffsetForView:[self TPKeyboardAvoiding_findFirstResponderBeneathView:self]
|
||||
withViewingAreaHeight:visibleSpace]);
|
||||
|
||||
// Ordinarily we'd use -setContentOffset:animated:YES here, but it does not appear to
|
||||
// scroll to the desired content offset. So we wrap in our own animation block.
|
||||
[UIView animateWithDuration:0.25 animations:^{
|
||||
[self setContentOffset:idealOffset animated: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;
|
||||
}
|
||||
|
||||
- (void)TPKeyboardAvoiding_findTextFieldAfterTextField:(UIView*)priorTextField beneathView:(UIView*)view minY:(CGFloat*)minY foundView:(UIView**)foundView {
|
||||
// Search recursively for text field or text view below priorTextField
|
||||
CGFloat priorFieldOffset = CGRectGetMinY([self convertRect:priorTextField.frame fromView:priorTextField.superview]);
|
||||
for ( UIView *childView in view.subviews ) {
|
||||
if ( childView.hidden ) continue;
|
||||
if ( ([childView isKindOfClass:[UITextField class]] || [childView isKindOfClass:[UITextView class]]) && childView.isUserInteractionEnabled) {
|
||||
CGRect frame = [self convertRect:childView.frame fromView:view];
|
||||
if ( childView != priorTextField
|
||||
&& CGRectGetMinY(frame) >= priorFieldOffset
|
||||
&& CGRectGetMinY(frame) < *minY &&
|
||||
!(frame.origin.y == priorTextField.frame.origin.y
|
||||
&& frame.origin.x < priorTextField.frame.origin.x) ) {
|
||||
*minY = CGRectGetMinY(frame);
|
||||
*foundView = childView;
|
||||
}
|
||||
} else {
|
||||
[self TPKeyboardAvoiding_findTextFieldAfterTextField:priorTextField beneathView:childView minY:minY foundView:foundView];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (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 - (CGRectGetMaxY(keyboardRect) - CGRectGetMaxY(self.bounds));
|
||||
return newInset;
|
||||
}
|
||||
|
||||
-(CGFloat)TPKeyboardAvoiding_idealOffsetForView:(UIView *)view withViewingAreaHeight:(CGFloat)viewAreaHeight {
|
||||
CGSize contentSize = self.contentSize;
|
||||
CGFloat offset = 0.0;
|
||||
|
||||
CGRect subviewRect = [view convertRect:view.bounds toView:self];
|
||||
|
||||
// Attempt to center the subview in the visible space, but if that means there will be less than kMinimumScrollOffsetPadding
|
||||
// pixels above the view, then substitute kMinimumScrollOffsetPadding
|
||||
CGFloat padding = (viewAreaHeight - subviewRect.size.height) / 2;
|
||||
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 - self.contentInset.top;
|
||||
|
||||
// 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.
|
||||
if ( offset > (contentSize.height - viewAreaHeight) ) {
|
||||
offset = contentSize.height - viewAreaHeight;
|
||||
}
|
||||
|
||||
// Constrain the new contentOffset so we can't scroll past the top, taking contentInsets into account
|
||||
if ( offset < -self.contentInset.top ) {
|
||||
offset = -self.contentInset.top;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
- (void)TPKeyboardAvoiding_initializeView:(UIView*)view {
|
||||
if ( [view isKindOfClass:[UITextField class]] && ((UITextField*)view).returnKeyType == UIReturnKeyDefault && (![(id)view delegate] || [(UIScrollView*)view delegate] == (id<UIScrollViewDelegate>)self) ) {
|
||||
[(UIScrollView*)view setDelegate:(id<UIScrollViewDelegate>)self];
|
||||
UIView *otherView = nil;
|
||||
CGFloat minY = CGFLOAT_MAX;
|
||||
[self TPKeyboardAvoiding_findTextFieldAfterTextField:view beneathView:self minY:&minY foundView:&otherView];
|
||||
|
||||
if ( otherView ) {
|
||||
((UITextField*)view).returnKeyType = UIReturnKeyNext;
|
||||
} else {
|
||||
((UITextField*)view).returnKeyType = UIReturnKeyDone;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation TPKeyboardAvoidingState
|
||||
@end
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
#import "UICompositeViewController.h"
|
||||
#import "UILinphoneTextField.h"
|
||||
#import "LinphoneUI/UILinphoneButton.h"
|
||||
#import "TPKeyboardAvoidingScrollView.h"
|
||||
|
||||
@interface WizardViewController : TPMultiLayoutViewController
|
||||
<UITextFieldDelegate,
|
||||
|
|
@ -37,7 +38,7 @@
|
|||
NSMutableArray *historyViews;
|
||||
}
|
||||
|
||||
@property (nonatomic, strong) IBOutlet UIScrollView *contentView;
|
||||
@property(nonatomic, strong) IBOutlet TPKeyboardAvoidingScrollView *contentView;
|
||||
|
||||
@property (nonatomic, strong) IBOutlet UIView *welcomeView;
|
||||
@property (nonatomic, strong) IBOutlet UIView *choiceView;
|
||||
|
|
@ -56,7 +57,6 @@
|
|||
@property (nonatomic, strong) IBOutlet UIButton *externalAccountButton;
|
||||
@property (strong, nonatomic) IBOutlet UIButton *remoteProvisioningButton;
|
||||
@property (strong, nonatomic) IBOutlet UILinphoneButton *registerButton;
|
||||
@property (strong, nonatomic) IBOutlet UILinphoneButton *purchaseButton;
|
||||
|
||||
@property (strong, nonatomic) IBOutlet UILinphoneTextField *createAccountUsername;
|
||||
@property (strong, nonatomic) IBOutlet UILinphoneTextField *connectAccountUsername;
|
||||
|
|
@ -83,7 +83,6 @@
|
|||
- (IBAction)onExternalAccountClick:(id)sender;
|
||||
- (IBAction)onCheckValidationClick:(id)sender;
|
||||
- (IBAction)onRemoteProvisioningClick:(id)sender;
|
||||
- (IBAction)onPurchaseAccountClick:(id)sender;
|
||||
|
||||
- (IBAction)onSignInClick:(id)sender;
|
||||
- (IBAction)onSignInExternalClick:(id)sender;
|
||||
|
|
|
|||
|
|
@ -109,7 +109,6 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
|
||||
- (void)viewWillAppear:(BOOL)animated {
|
||||
[super viewWillAppear:animated];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(registrationUpdateEvent:)
|
||||
name:kLinphoneRegistrationUpdate
|
||||
|
|
@ -118,39 +117,11 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
selector:@selector(configuringUpdate:)
|
||||
name:kLinphoneConfiguringStateUpdate
|
||||
object:nil];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(keyboardWillShow:)
|
||||
name:UIKeyboardWillShowNotification
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(keyboardWillHide:)
|
||||
name:UIKeyboardWillHideNotification
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(inAppPurchaseNotification:)
|
||||
name:kIAPPurchaseSucceeded
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(inAppPurchaseNotification:)
|
||||
name:kIAPPurchaseTrying
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(inAppPurchaseNotification:)
|
||||
name:kIAPPurchaseFailed
|
||||
object:nil];
|
||||
}
|
||||
|
||||
- (void)viewWillDisappear:(BOOL)animated {
|
||||
[super viewWillDisappear:animated];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:kLinphoneRegistrationUpdate object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:kLinphoneConfiguringStateUpdate object:nil];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:kIAPPurchaseFailed object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:kIAPPurchaseTrying object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:kIAPPurchaseSucceeded object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
|
|
@ -183,12 +154,6 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
text.placeholder = NSLocalizedString(@"Username", nil);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL mustPurchaseNewAccount =
|
||||
([[[LinphoneManager instance] iapManager] enabled] &&
|
||||
[[LinphoneManager instance] lpConfigStringForKey:@"paid_account_id" forSection:@"in_app_purchase"] != nil);
|
||||
_registerButton.hidden = mustPurchaseNewAccount;
|
||||
_purchaseButton.hidden = !mustPurchaseNewAccount;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
|
@ -882,46 +847,6 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
}
|
||||
}
|
||||
|
||||
- (void)inAppPurchaseNotification:(NSNotification *)notification {
|
||||
BOOL wasWaitingForInApp = (currentView == createAccountView);
|
||||
NSString *paidAccountID =
|
||||
[[LinphoneManager instance] lpConfigStringForKey:@"paid_account_id" forSection:@"in_app_purchase"];
|
||||
if (wasWaitingForInApp && [paidAccountID isEqualToString:[notification.userInfo objectForKey:@"product_id"]]) {
|
||||
if ([notification.name isEqual:kIAPPurchaseTrying]) {
|
||||
[waitView setHidden:false];
|
||||
} else if ([notification.name isEqual:kIAPPurchaseFailed]) {
|
||||
[waitView setHidden:true];
|
||||
} else if ([notification.name isEqual:kIAPPurchaseSucceeded]) {
|
||||
[waitView setHidden:true];
|
||||
// now that the purchase is made, let's create the account.
|
||||
[self onPurchaseAccountClick:self];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)onPurchaseAccountClick:(id)sender {
|
||||
UITextField *username_tf = [WizardViewController findTextField:ViewElement_Username view:contentView];
|
||||
NSString *username = username_tf.text;
|
||||
NSString *password = [WizardViewController findTextField:ViewElement_Password view:contentView].text;
|
||||
NSString *password2 = [WizardViewController findTextField:ViewElement_Password2 view:contentView].text;
|
||||
NSString *email = [WizardViewController findTextField:ViewElement_Email view:contentView].text;
|
||||
|
||||
if ([self verificationRegisterWithUsername:username password:password password2:password2 email:email]) {
|
||||
InAppProductsManager *iapm = [[LinphoneManager instance] iapManager];
|
||||
// if has already purchased, continue
|
||||
if ([iapm isPurchasedWithID:[[LinphoneManager instance] lpConfigStringForKey:@"paid_account_id"
|
||||
forSection:@"in_app_purchase"]]) {
|
||||
username = [username lowercaseString];
|
||||
[username_tf setText:username];
|
||||
NSString *identity = [self identityFromUsername:username];
|
||||
[self checkUserExist:identity];
|
||||
} else {
|
||||
[iapm purchaseAccount:username withPassword:password andEmail:email monthly:FALSE];
|
||||
// inAppPurchaseNotification will take care of bringing us to the next view now
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)onProvisionedLoginClick:(id)sender {
|
||||
NSString *username = provisionedUsername.text;
|
||||
NSString *password = provisionedPassword.text;
|
||||
|
|
@ -946,6 +871,10 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
}
|
||||
}
|
||||
|
||||
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
|
||||
[contentView contentSizeToFit];
|
||||
}
|
||||
|
||||
- (IBAction)onViewTap:(id)sender {
|
||||
[LinphoneUtils findAndResignFirstResponder:currentView];
|
||||
}
|
||||
|
|
@ -1009,71 +938,6 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
[self registrationUpdate:[[notif.userInfo objectForKey:@"state"] intValue] message:message];
|
||||
}
|
||||
|
||||
#pragma mark - Keyboard Event Functions
|
||||
|
||||
- (void)keyboardWillHide:(NSNotification *)notif {
|
||||
// CGRect beginFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
|
||||
// CGRect endFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
|
||||
UIViewAnimationCurve curve = [[[notif userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];
|
||||
NSTimeInterval duration = [[[notif userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
|
||||
[UIView beginAnimations:@"resize" context:nil];
|
||||
[UIView setAnimationDuration:duration];
|
||||
[UIView setAnimationCurve:curve];
|
||||
[UIView setAnimationBeginsFromCurrentState:TRUE];
|
||||
|
||||
// Move view
|
||||
UIEdgeInsets inset = {0, 0, 0, 0};
|
||||
[contentView setContentInset:inset];
|
||||
[contentView setScrollIndicatorInsets:inset];
|
||||
[contentView setShowsVerticalScrollIndicator:FALSE];
|
||||
|
||||
[UIView commitAnimations];
|
||||
}
|
||||
|
||||
- (void)keyboardWillShow:(NSNotification *)notif {
|
||||
// CGRect beginFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
|
||||
CGRect endFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
|
||||
UIViewAnimationCurve curve = [[[notif userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];
|
||||
NSTimeInterval duration = [[[notif userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
|
||||
[UIView beginAnimations:@"resize" context:nil];
|
||||
[UIView setAnimationDuration:duration];
|
||||
[UIView setAnimationCurve:curve];
|
||||
[UIView setAnimationBeginsFromCurrentState:TRUE];
|
||||
|
||||
if (([[UIDevice currentDevice].systemVersion floatValue] < 8) &&
|
||||
UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
|
||||
int width = endFrame.size.height;
|
||||
endFrame.size.height = endFrame.size.width;
|
||||
endFrame.size.width = width;
|
||||
}
|
||||
|
||||
// Change inset
|
||||
{
|
||||
UIEdgeInsets inset = {0, 0, 0, 0};
|
||||
CGRect frame = [contentView frame];
|
||||
CGRect rect = [PhoneMainView instance].view.bounds;
|
||||
CGPoint pos = {frame.size.width, frame.size.height};
|
||||
CGPoint gPos =
|
||||
[contentView convertPoint:pos
|
||||
toView:[UIApplication sharedApplication].keyWindow.rootViewController.view]; // Bypass
|
||||
// IOS bug
|
||||
// on
|
||||
// landscape
|
||||
// mode
|
||||
inset.bottom = -(rect.size.height - gPos.y - endFrame.size.height);
|
||||
if (inset.bottom < 0)
|
||||
inset.bottom = 0;
|
||||
|
||||
[contentView setContentInset:inset];
|
||||
[contentView setScrollIndicatorInsets:inset];
|
||||
CGRect fieldFrame = activeTextField.frame;
|
||||
fieldFrame.origin.y += fieldFrame.size.height;
|
||||
[contentView scrollRectToVisible:fieldFrame animated:TRUE];
|
||||
[contentView setShowsVerticalScrollIndicator:TRUE];
|
||||
}
|
||||
[UIView commitAnimations];
|
||||
}
|
||||
|
||||
#pragma mark - XMLRPCConnectionDelegate Functions
|
||||
|
||||
- (void)request:(XMLRPCRequest *)request didReceiveResponse:(XMLRPCResponse *)response {
|
||||
|
|
|
|||
|
|
@ -163,6 +163,11 @@
|
|||
639CEB061A1DF4F1004DE38F /* UIChatRoomCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639CEB081A1DF4F1004DE38F /* UIChatRoomCell.xib */; };
|
||||
639CEB091A1DF4FA004DE38F /* UIChatCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639CEB0B1A1DF4FA004DE38F /* UIChatCell.xib */; };
|
||||
63A4280A1B26F576000DAB93 /* libSKP_SILK_SDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226183AA1472527D0037138E /* libSKP_SILK_SDK.a */; };
|
||||
63B81A0C1B57DA33009604A6 /* LICENSE.txt in Resources */ = {isa = PBXBuildFile; fileRef = 63B81A031B57DA33009604A6 /* LICENSE.txt */; };
|
||||
63B81A0D1B57DA33009604A6 /* TPKeyboardAvoidingCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63B81A051B57DA33009604A6 /* TPKeyboardAvoidingCollectionView.m */; };
|
||||
63B81A0E1B57DA33009604A6 /* TPKeyboardAvoidingScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63B81A071B57DA33009604A6 /* TPKeyboardAvoidingScrollView.m */; };
|
||||
63B81A0F1B57DA33009604A6 /* TPKeyboardAvoidingTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63B81A091B57DA33009604A6 /* TPKeyboardAvoidingTableView.m */; };
|
||||
63B81A101B57DA33009604A6 /* UIScrollView+TPKeyboardAvoidingAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 63B81A0B1B57DA33009604A6 /* UIScrollView+TPKeyboardAvoidingAdditions.m */; };
|
||||
63C458261B5680AC009F2D7E /* ring.wav in Resources */ = {isa = PBXBuildFile; fileRef = 2237D4081084D7A9001383EE /* ring.wav */; };
|
||||
63CD4B4F1A5AAC8C00B84282 /* DTAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63CD4B4E1A5AAC8C00B84282 /* DTAlertView.m */; };
|
||||
63D2680F1B174A5E00A2CC11 /* numpad_one_voicemail_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 63D2680D1B174A5E00A2CC11 /* numpad_one_voicemail_default.png */; };
|
||||
|
|
@ -1094,6 +1099,15 @@
|
|||
639CEB0A1A1DF4FA004DE38F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UIChatCell.xib; sourceTree = "<group>"; };
|
||||
639CEB0C1A1DF528004DE38F /* fr */ = {isa = PBXFileReference; fileEncoding = 2483028224; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/UICallCell.strings; sourceTree = "<group>"; };
|
||||
639CEB0D1A1DF52C004DE38F /* ru */ = {isa = PBXFileReference; fileEncoding = 2483028224; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/UICallCell.strings; sourceTree = "<group>"; };
|
||||
63B81A031B57DA33009604A6 /* LICENSE.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE.txt; sourceTree = "<group>"; };
|
||||
63B81A041B57DA33009604A6 /* TPKeyboardAvoidingCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPKeyboardAvoidingCollectionView.h; sourceTree = "<group>"; };
|
||||
63B81A051B57DA33009604A6 /* TPKeyboardAvoidingCollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPKeyboardAvoidingCollectionView.m; sourceTree = "<group>"; };
|
||||
63B81A061B57DA33009604A6 /* TPKeyboardAvoidingScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPKeyboardAvoidingScrollView.h; sourceTree = "<group>"; };
|
||||
63B81A071B57DA33009604A6 /* TPKeyboardAvoidingScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPKeyboardAvoidingScrollView.m; sourceTree = "<group>"; };
|
||||
63B81A081B57DA33009604A6 /* TPKeyboardAvoidingTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPKeyboardAvoidingTableView.h; sourceTree = "<group>"; };
|
||||
63B81A091B57DA33009604A6 /* TPKeyboardAvoidingTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPKeyboardAvoidingTableView.m; sourceTree = "<group>"; };
|
||||
63B81A0A1B57DA33009604A6 /* UIScrollView+TPKeyboardAvoidingAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIScrollView+TPKeyboardAvoidingAdditions.h"; sourceTree = "<group>"; };
|
||||
63B81A0B1B57DA33009604A6 /* UIScrollView+TPKeyboardAvoidingAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIScrollView+TPKeyboardAvoidingAdditions.m"; sourceTree = "<group>"; };
|
||||
63CD4B4D1A5AAC8C00B84282 /* DTAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTAlertView.h; sourceTree = "<group>"; };
|
||||
63CD4B4E1A5AAC8C00B84282 /* DTAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTAlertView.m; sourceTree = "<group>"; };
|
||||
63D2680D1B174A5E00A2CC11 /* numpad_one_voicemail_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_one_voicemail_default.png; path = Resources/numpad_one_voicemail_default.png; sourceTree = "<group>"; };
|
||||
|
|
@ -2405,6 +2419,23 @@
|
|||
path = TestsLiblinphone;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
63B81A021B57DA33009604A6 /* TPKeyboardAvoiding */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
63B81A031B57DA33009604A6 /* LICENSE.txt */,
|
||||
63B81A041B57DA33009604A6 /* TPKeyboardAvoidingCollectionView.h */,
|
||||
63B81A051B57DA33009604A6 /* TPKeyboardAvoidingCollectionView.m */,
|
||||
63B81A061B57DA33009604A6 /* TPKeyboardAvoidingScrollView.h */,
|
||||
63B81A071B57DA33009604A6 /* TPKeyboardAvoidingScrollView.m */,
|
||||
63B81A081B57DA33009604A6 /* TPKeyboardAvoidingTableView.h */,
|
||||
63B81A091B57DA33009604A6 /* TPKeyboardAvoidingTableView.m */,
|
||||
63B81A0A1B57DA33009604A6 /* UIScrollView+TPKeyboardAvoidingAdditions.h */,
|
||||
63B81A0B1B57DA33009604A6 /* UIScrollView+TPKeyboardAvoidingAdditions.m */,
|
||||
);
|
||||
name = TPKeyboardAvoiding;
|
||||
path = Utils/TPKeyboardAvoiding;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D326483415887D4400930C67 /* Utils */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -2417,6 +2448,7 @@
|
|||
D32B9DFB15A2F131000B6DEC /* FastAddressBook.m */,
|
||||
6371579F1B283FE200C91677 /* FileTransferDelegate.h */,
|
||||
637157A01B283FE200C91677 /* FileTransferDelegate.m */,
|
||||
63B81A021B57DA33009604A6 /* TPKeyboardAvoiding */,
|
||||
D3ED40141602172200BF332B /* GrowingTextView */,
|
||||
D3807FC715C2894A005BE9BC /* InAppSettingsKit */,
|
||||
D3B90E1115C2CB5700F64F8C /* NinePatch.xcodeproj */,
|
||||
|
|
@ -3735,6 +3767,7 @@
|
|||
D339890215C6DD1600CAF1E4 /* video_on_over_landscape~ipad.png in Resources */,
|
||||
D339890615C6E16F00CAF1E4 /* dialer_alt_back_default_landscape~ipad.png in Resources */,
|
||||
D339890815C6E16F00CAF1E4 /* dialer_alt_back_over_landscape~ipad.png in Resources */,
|
||||
63B81A0C1B57DA33009604A6 /* LICENSE.txt in Resources */,
|
||||
D30BBD1815D402A7000F93DD /* contact_ok_disabled.png in Resources */,
|
||||
D3804E6015D92A57008072A5 /* msg.caf in Resources */,
|
||||
D3804E6215D92A57008072A5 /* msg.wav in Resources */,
|
||||
|
|
@ -3948,6 +3981,7 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
63B81A0F1B57DA33009604A6 /* TPKeyboardAvoidingTableView.m in Sources */,
|
||||
1D60589B0D05DD56006BFB54 /* main.m in Sources */,
|
||||
1D3623260D0F684500981E51 /* LinphoneAppDelegate.m in Sources */,
|
||||
22F2508E107141E100AC9B3F /* DialerViewController.m in Sources */,
|
||||
|
|
@ -3984,10 +4018,13 @@
|
|||
D35E7581159328EB0066B1C1 /* UIAddressTextField.m in Sources */,
|
||||
D35E7597159460580066B1C1 /* ChatViewController.m in Sources */,
|
||||
D35E759F159460B70066B1C1 /* SettingsViewController.m in Sources */,
|
||||
63B81A101B57DA33009604A6 /* UIScrollView+TPKeyboardAvoidingAdditions.m in Sources */,
|
||||
F03CA84318C72F1A0008889D /* UITextViewNoDefine.m in Sources */,
|
||||
63B81A0D1B57DA33009604A6 /* TPKeyboardAvoidingCollectionView.m in Sources */,
|
||||
D37DC6C11594AE1800B2A5EB /* LinphoneCoreSettingsStore.m in Sources */,
|
||||
63CD4B4F1A5AAC8C00B84282 /* DTAlertView.m in Sources */,
|
||||
D3EA53FD159850E80037DC6B /* LinphoneManager.m in Sources */,
|
||||
63B81A0E1B57DA33009604A6 /* TPKeyboardAvoidingScrollView.m in Sources */,
|
||||
D3EA540D1598528B0037DC6B /* ChatTableViewController.m in Sources */,
|
||||
D3EA5411159853750037DC6B /* UIChatCell.m in Sources */,
|
||||
D3F26BF115986B73005F9CAB /* IncomingCallViewController.m in Sources */,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue