[mobile] enable demo functionality. bring iOS app up to Android capabilities.

15 views
Skip to first unread message

Hyang-Ah Hana Kim (Gerrit)

unread,
Oct 29, 2021, 11:09:03 PM10/29/21
to Hyang-Ah Hana Kim, Robert Engels, goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Go Bot, Peter Weinberger, Rob Pike, golang-co...@googlegroups.com

Hyang-Ah Hana Kim submitted this change.

View Change



12 is the latest approved patch-set.
No files were changed between the latest approved patch-set and the submitted one.

Approvals: Hyang-Ah Hana Kim: Looks good to me, approved; Trusted Peter Weinberger: Trusted
example/ivy/ios: enable demo functionality

And bring iOS app up to Android capabilities.

Fixes golang/go#48694

Change-Id: I0e853cab102e34053ecdb17edb99644aa2f8651a
Reviewed-on: https://go-review.googlesource.com/c/mobile/+/357977
Reviewed-by: Hyang-Ah Hana Kim <hya...@gmail.com>
Trust: Hyang-Ah Hana Kim <hya...@gmail.com>
Trust: Peter Weinberger <p...@google.com>
---
M example/ivy/ios/ivy/IvyController.m
M example/ivy/ios/ivy/IvyController.h
M example/ivy/ios/ivy/Info.plist
M example/ivy/ios/README.md
M example/ivy/ios/ivy/Images.xcassets/AppIcon.appiconset/Contents.json
M example/ivy/ios/ivy/tape.html
M example/ivy/ios/ivy.xcodeproj/project.pbxproj
M example/ivy/ios/ivy/Base.lproj/Main.storyboard
8 files changed, 309 insertions(+), 136 deletions(-)

diff --git a/example/ivy/ios/README.md b/example/ivy/ios/README.md
index 453ccbc..bfbaa19 100644
--- a/example/ivy/ios/README.md
+++ b/example/ivy/ios/README.md
@@ -17,7 +17,7 @@
go mod init work
go get -d golang.org/x/mobile/bind@latest
go get -d robpike.io/ivy/mobile
-gomobile bind -target=ios,iossimulator,maccatalyst,macos robpike.io/ivy/mobile
+gomobile bind -target=ios,iossimulator,maccatalyst,macos robpike.io/ivy/mobile robpike.io/ivy/demo
```

Place the Mobile.xcframework directory in this directory, and
diff --git a/example/ivy/ios/ivy.xcodeproj/project.pbxproj b/example/ivy/ios/ivy.xcodeproj/project.pbxproj
index aeb1d30..f183085 100644
--- a/example/ivy/ios/ivy.xcodeproj/project.pbxproj
+++ b/example/ivy/ios/ivy.xcodeproj/project.pbxproj
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
- objectVersion = 46;
+ objectVersion = 52;
objects = {

/* Begin PBXBuildFile section */
@@ -316,12 +316,16 @@
);
INFOPLIST_FILE = ivy/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)",
);
ONLY_ACTIVE_ARCH = NO;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.google.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = ivy;
STRIP_STYLE = debugging;
SUPPORTS_MACCATALYST = YES;
@@ -342,13 +346,16 @@
);
INFOPLIST_FILE = ivy/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)",
);
ONLY_ACTIVE_ARCH = NO;
- PRODUCT_BUNDLE_IDENTIFIER = "com.google.$(PRODUCT_NAME:rfc1034identifier)";
+ PRODUCT_BUNDLE_IDENTIFIER = "com.google.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = ivy;
STRIP_STYLE = debugging;
SUPPORTS_MACCATALYST = YES;
diff --git a/example/ivy/ios/ivy/Base.lproj/Main.storyboard b/example/ivy/ios/ivy/Base.lproj/Main.storyboard
index db250c1..18a65a9 100644
--- a/example/ivy/ios/ivy/Base.lproj/Main.storyboard
+++ b/example/ivy/ios/ivy/Base.lproj/Main.storyboard
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19158" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="mTw-C8-NzX">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19162" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="mTw-C8-NzX">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<accessibilityOverrides isEnabled="YES"/>
<dependencies>
<deployment identifier="iOS"/>
- <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19141"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19144"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
@@ -55,15 +55,38 @@
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
- <textField opaque="NO" clipsSubviews="YES" tag="1" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Type an expression" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="9SS-TP-C7c" userLabel="InputField">
- <rect key="frame" x="20" y="817" width="374" height="34"/>
- <color key="backgroundColor" red="0.98823529409999999" green="0.98039215690000003" blue="0.81176470590000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
- <rect key="contentStretch" x="1" y="1" width="1" height="1"/>
- <fontDescription key="fontDescription" name="Menlo-Bold" family="Menlo" pointSize="14"/>
- <textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="alphabet" keyboardAppearance="alert" enablesReturnKeyAutomatically="YES"/>
- </textField>
+ <stackView opaque="NO" contentMode="scaleToFill" horizontalCompressionResistancePriority="1000" verticalCompressionResistancePriority="1000" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="Cn1-rU-W3R">
+ <rect key="frame" x="20" y="831" width="374" height="31"/>
+ <subviews>
+ <textField opaque="NO" clipsSubviews="YES" tag="1" contentMode="scaleToFill" horizontalHuggingPriority="249" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Type an expression" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="9SS-TP-C7c" userLabel="InputField">
+ <rect key="frame" x="0.0" y="0.0" width="301.5" height="31"/>
+ <color key="backgroundColor" red="0.98823529409999999" green="0.98039215690000003" blue="0.81176470590000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+ <rect key="contentStretch" x="1" y="1" width="1" height="1"/>
+ <fontDescription key="fontDescription" name="Menlo-Bold" family="Menlo" pointSize="14"/>
+ <textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="alphabet" keyboardAppearance="alert" enablesReturnKeyAutomatically="YES" smartDashesType="no" smartInsertDeleteType="no" smartQuotesType="no"/>
+ </textField>
+ <button opaque="NO" contentMode="scaleToFill" horizontalCompressionResistancePriority="1000" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="eO6-bM-CwW">
+ <rect key="frame" x="301.5" y="0.0" width="72.5" height="31"/>
+ <accessibility key="accessibilityConfiguration" label="OK"/>
+ <constraints>
+ <constraint firstAttribute="height" constant="31" id="1nb-CV-bfg"/>
+ </constraints>
+ <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+ <state key="normal" title="Button" image="return" catalog="system"/>
+ <connections>
+ <action selector="okPressed:" destination="BYZ-38-t0r" eventType="touchUpInside" id="258-zN-fwW"/>
+ </connections>
+ </button>
+ </subviews>
+ <constraints>
+ <constraint firstItem="9SS-TP-C7c" firstAttribute="trailing" secondItem="eO6-bM-CwW" secondAttribute="leading" id="9Fe-Sf-U5p"/>
+ <constraint firstItem="eO6-bM-CwW" firstAttribute="top" secondItem="9SS-TP-C7c" secondAttribute="top" id="9hv-aL-4z2"/>
+ <constraint firstItem="eO6-bM-CwW" firstAttribute="trailing" secondItem="Cn1-rU-W3R" secondAttribute="trailing" id="A4G-YY-4Gn"/>
+ <constraint firstItem="9SS-TP-C7c" firstAttribute="leading" secondItem="Cn1-rU-W3R" secondAttribute="leading" id="i2m-BU-Q4a"/>
+ </constraints>
+ </stackView>
<wkWebView opaque="NO" tag="2" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" layoutMarginsFollowReadableWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ga1-Py-9re">
- <rect key="frame" x="20" y="88" width="374" height="721"/>
+ <rect key="frame" x="20" y="88" width="374" height="737"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<wkWebViewConfiguration key="configuration">
<audiovisualMediaTypes key="mediaTypesRequiringUserActionForPlayback" none="YES"/>
@@ -73,29 +96,44 @@
</subviews>
<color key="backgroundColor" red="0.9882352941176471" green="0.98039215686274506" blue="0.81176470588235294" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
- <constraint firstItem="ga1-Py-9re" firstAttribute="trailing" secondItem="9SS-TP-C7c" secondAttribute="trailing" id="3b6-rZ-W4R"/>
- <constraint firstItem="9SS-TP-C7c" firstAttribute="top" secondItem="ga1-Py-9re" secondAttribute="bottom" constant="8" id="B3O-hi-PRD"/>
+ <constraint firstItem="Cn1-rU-W3R" firstAttribute="trailing" secondItem="8bC-Xf-vdC" secondAttribute="trailingMargin" id="7DU-Hc-uk7"/>
+ <constraint firstItem="Cn1-rU-W3R" firstAttribute="bottom" secondItem="wfy-db-euE" secondAttribute="top" id="8mr-vY-R1v"/>
+ <constraint firstItem="ga1-Py-9re" firstAttribute="bottom" secondItem="Cn1-rU-W3R" secondAttribute="top" constant="-6" id="BX0-OH-IJ4"/>
<constraint firstItem="ga1-Py-9re" firstAttribute="trailing" secondItem="8bC-Xf-vdC" secondAttribute="trailingMargin" id="Fxh-TE-BtG"/>
- <constraint firstItem="ga1-Py-9re" firstAttribute="leading" secondItem="9SS-TP-C7c" secondAttribute="leading" id="MhN-JS-MpC"/>
- <constraint firstItem="wfy-db-euE" firstAttribute="top" secondItem="9SS-TP-C7c" secondAttribute="bottom" constant="11" id="Yvi-br-VHk"/>
+ <constraint firstItem="Cn1-rU-W3R" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" id="LPE-LO-nct"/>
<constraint firstItem="ga1-Py-9re" firstAttribute="top" secondItem="8bC-Xf-vdC" secondAttribute="topMargin" id="p9M-sp-ZwC"/>
<constraint firstItem="ga1-Py-9re" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" id="pOi-3s-hrr"/>
</constraints>
</view>
<navigationItem key="navigationItem" title="Ivy" id="9fD-A5-WTg">
- <barButtonItem key="rightBarButtonItem" title="Help" id="aDa-GJ-VpX">
+ <barButtonItem key="leftBarButtonItem" title="Clear" id="70x-xp-aiX">
<connections>
- <segue destination="rfr-rm-AXI" kind="show" id="kuc-xA-dyM"/>
+ <action selector="clear:" destination="BYZ-38-t0r" id="n7k-fg-dil"/>
</connections>
</barButtonItem>
+ <rightBarButtonItems>
+ <barButtonItem title="Help" id="aDa-GJ-VpX">
+ <connections>
+ <segue destination="rfr-rm-AXI" kind="show" id="kuc-xA-dyM"/>
+ </connections>
+ </barButtonItem>
+ <barButtonItem title="Demo" id="ZN2-PQ-aPW">
+ <connections>
+ <action selector="demo:" destination="BYZ-38-t0r" id="NpG-yh-wMO"/>
+ </connections>
+ </barButtonItem>
+ </rightBarButtonItems>
</navigationItem>
<connections>
- <outlet property="bottomConstraint" destination="Yvi-br-VHk" id="EKm-WV-Y1w"/>
+ <outlet property="bottomConstraint" destination="8mr-vY-R1v" id="BqX-Do-vtq"/>
+ <outlet property="input" destination="9SS-TP-C7c" id="jUA-25-4WI"/>
+ <outlet property="okButton" destination="eO6-bM-CwW" id="o9U-hD-NDr"/>
+ <outlet property="tape" destination="ga1-Py-9re" id="00M-9S-MAl"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
- <point key="canvasLocation" x="990.40178571428567" y="382.60869565217394"/>
+ <point key="canvasLocation" x="989.85507246376824" y="382.36607142857139"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="ZgV-45-Pf8">
@@ -130,4 +168,7 @@
<point key="canvasLocation" x="271" y="386"/>
</scene>
</scenes>
+ <resources>
+ <image name="return" catalog="system" width="128" height="101"/>
+ </resources>
</document>
diff --git a/example/ivy/ios/ivy/Images.xcassets/AppIcon.appiconset/Contents.json b/example/ivy/ios/ivy/Images.xcassets/AppIcon.appiconset/Contents.json
index 466150b..b6cf353 100644
--- a/example/ivy/ios/ivy/Images.xcassets/AppIcon.appiconset/Contents.json
+++ b/example/ivy/ios/ivy/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -151,6 +151,13 @@
"size" : "29x29"
},
{
+ "idiom" : "watch",
+ "role" : "notificationCenter",
+ "scale" : "2x",
+ "size" : "33x33",
+ "subtype" : "45mm"
+ },
+ {
"filename" : "icon-80.png",
"idiom" : "watch",
"role" : "appLauncher",
@@ -167,6 +174,13 @@
"subtype" : "40mm"
},
{
+ "idiom" : "watch",
+ "role" : "appLauncher",
+ "scale" : "2x",
+ "size" : "46x46",
+ "subtype" : "41mm"
+ },
+ {
"filename" : "icon-100.png",
"idiom" : "watch",
"role" : "appLauncher",
@@ -175,6 +189,13 @@
"subtype" : "44mm"
},
{
+ "idiom" : "watch",
+ "role" : "appLauncher",
+ "scale" : "2x",
+ "size" : "51x51",
+ "subtype" : "45mm"
+ },
+ {
"filename" : "icon-172.png",
"idiom" : "watch",
"role" : "quickLook",
@@ -199,6 +220,13 @@
"subtype" : "44mm"
},
{
+ "idiom" : "watch",
+ "role" : "quickLook",
+ "scale" : "2x",
+ "size" : "117x117",
+ "subtype" : "45mm"
+ },
+ {
"filename" : "icon-1024.png",
"idiom" : "watch-marketing",
"scale" : "1x",
diff --git a/example/ivy/ios/ivy/Info.plist b/example/ivy/ios/ivy/Info.plist
index aad4905..9438af6 100644
--- a/example/ivy/ios/ivy/Info.plist
+++ b/example/ivy/ios/ivy/Info.plist
@@ -11,7 +11,7 @@
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
- <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <string>com.google.$(PRODUCT_NAME:rfc1034identifier)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
diff --git a/example/ivy/ios/ivy/IvyController.h b/example/ivy/ios/ivy/IvyController.h
index 0d78d9c..e76bf2f 100644
--- a/example/ivy/ios/ivy/IvyController.h
+++ b/example/ivy/ios/ivy/IvyController.h
@@ -14,8 +14,13 @@
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomConstraint;

// A text input field coupled to an output "tape", rendered with a WKWebView.
-@property (strong, nonatomic) UITextField *input;
+@property (weak, nonatomic) IBOutlet UITextField *input;
@property (strong, nonatomic) Suggestion *suggestionView;
-@property (strong, nonatomic) WKWebView *tape;
+@property (weak, nonatomic) IBOutlet WKWebView *tape;
+@property (weak, nonatomic) IBOutlet UIButton *okButton;
+
+- (IBAction)clear:(id)sender;
+- (IBAction)demo:(id)sender;
+- (IBAction)okPressed:(id)sender;

@end
diff --git a/example/ivy/ios/ivy/IvyController.m b/example/ivy/ios/ivy/IvyController.m
index 42e4dd7..ecac33f 100644
--- a/example/ivy/ios/ivy/IvyController.m
+++ b/example/ivy/ios/ivy/IvyController.m
@@ -9,50 +9,46 @@

@end

-@implementation IvyController
+@implementation IvyController {
+ NSArray *demo_lines;
+ int demo_index;
+}

- (void)viewDidLoad
{
[super viewDidLoad];
-
- self.input = (UITextField *)[self.view viewWithTag:1];
+
self.input.delegate = self;
self.input.autocorrectionType = UITextAutocorrectionTypeNo;
self.input.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
-
+
self.suggestionView = [[Suggestion alloc] init];
self.suggestionView.delegate = self;
-
- self.tape = [self.view viewWithTag:2];
+
self.tape.UIDelegate = self;
-
+ self->demo_lines=NULL;
+
+ [self.okButton setTitle:@"" forState:UIControlStateNormal];
+ [self.okButton setHidden:TRUE];
+
[[NSNotificationCenter defaultCenter]
- addObserver:self
- selector:@selector(textDidChange:)
- name:UITextFieldTextDidChangeNotification
- object:self.input];
+ addObserver:self
+ selector:@selector(textDidChange:)
+ name:UITextFieldTextDidChangeNotification
+ object:self.input];
[[NSNotificationCenter defaultCenter]
- addObserver:self
- selector:@selector(keyboardWillShow:)
- name:UIKeyboardWillShowNotification
- object:nil];
+ addObserver:self
+ selector:@selector(keyboardWillShow:)
+ name:UIKeyboardWillShowNotification
+ object:nil];
[[NSNotificationCenter defaultCenter]
- addObserver:self
- selector:@selector(keyboardWillHide:)
- name:UIKeyboardWillHideNotification
- object:nil];
-
- NSURL *bundleURL =
- [[NSBundle mainBundle] URLForResource:@"tape" withExtension:@"html"];
- NSURLRequest *request = [NSURLRequest requestWithURL:bundleURL];
- [self.tape loadRequest:request];
- self.tape.UIDelegate = self;
+ addObserver:self
+ selector:@selector(keyboardWillHide:)
+ name:UIKeyboardWillHideNotification
+ object:nil];
+
[self.input becomeFirstResponder];
-}
-
-- (void)viewDidAppear:(BOOL)animated
-{
- [self.view endEditing:YES];
+ [self clear:NULL];
}

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
@@ -75,33 +71,14 @@
}

- (BOOL)textField:(UITextField *)textField
- shouldChangeCharactersInRange:(NSRange)range
- replacementString:(NSString *)str
+shouldChangeCharactersInRange:(NSRange)range
+replacementString:(NSString *)str
{
if ([str isEqualToString:@"\n"]) {
- [self
- appendTape:[NSString stringWithFormat:@"<b>%@</b>", [self.input text]]];
- NSString *expr = [self.input.text stringByAppendingString:@"\n"];
- NSError *err;
- NSString *result = MobileEval(expr, &err);
- if (err != nil) {
- result = err.description;
- }
- result = [result
- stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
- result =
- [result stringByReplacingOccurrencesOfString:@"<" withString:@"&lt;"];
- result =
- [result stringByReplacingOccurrencesOfString:@">" withString:@"&gt;"];
- NSMutableArray *lines =
- (NSMutableArray *)[result componentsSeparatedByString:@"\n"];
- for (NSMutableString *line in lines) {
- [self appendTape:line];
- }
- self.input.text = @"";
+ [self enterPressed];
return NO;
}
-
+
return YES;
}

@@ -121,51 +98,98 @@
// Move the input text field up, as the keyboard has taken some of the screen.
NSDictionary *info = [aNotification userInfo];
CGRect kbFrame =
- [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
+ [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
NSNumber *duration =
- [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];
-
+ [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];
+
UIViewAnimationCurve keyboardTransitionAnimationCurve;
[[info valueForKey:UIKeyboardAnimationCurveUserInfoKey]
- getValue:&keyboardTransitionAnimationCurve];
+ getValue:&keyboardTransitionAnimationCurve];
UIViewAnimationOptions options =
- keyboardTransitionAnimationCurve | keyboardTransitionAnimationCurve << 16;
-
+ keyboardTransitionAnimationCurve | keyboardTransitionAnimationCurve << 16;
+
[UIView animateWithDuration:duration.floatValue
- delay:0
- options:options
- animations:^{
- self.bottomConstraint.constant = kbFrame.size.height;
+ delay:0
+ options:options
+ animations:^{
+ self.bottomConstraint.constant = 0 - kbFrame.size.height;
[self.view layoutIfNeeded];
- }
- completion:^(BOOL finished) {
+ }
+ completion:^(BOOL finished) {
[self scrollTapeToBottom];
- }];
+ }];
}

- (void)keyboardWillHide:(NSNotification *)aNotification
{
// Move the input text field back down.
NSDictionary *info = [aNotification userInfo];
+
NSNumber *duration =
- [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];
+ [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];

UIViewAnimationCurve keyboardTransitionAnimationCurve;
[[info valueForKey:UIKeyboardAnimationCurveUserInfoKey]
- getValue:&keyboardTransitionAnimationCurve];
+ getValue:&keyboardTransitionAnimationCurve];
UIViewAnimationOptions options =
- keyboardTransitionAnimationCurve | keyboardTransitionAnimationCurve << 16;
-
+ keyboardTransitionAnimationCurve | keyboardTransitionAnimationCurve << 16;
+
+ int offset = self.input.inputAccessoryView != NULL ? self.suggestionView.frame.size.height : 0;
+
[UIView animateWithDuration:duration.floatValue
- delay:0
- options:options
- animations:^{
- self.bottomConstraint.constant = 32;
+ delay:0
+ options:options
+ animations:^{
+ self.bottomConstraint.constant = 0 - offset;
[self.view layoutIfNeeded];
- }
- completion:^(BOOL finished) {
+ }
+ completion:^(BOOL finished) {
[self scrollTapeToBottom];
- }];
+ }];
+}
+
+- (void)enterPressed
+{
+ NSString *text = self.input.text;
+ if ([text isEqual:@""]){
+ if(self->demo_lines==NULL){
+ return;
+ }
+ while (demo_index < self->demo_lines.count) {
+ NSString *line = self->demo_lines[self->demo_index++];
+ if([line hasPrefix:@"#"]) {
+ [self appendTape:line tag:@"comment"];
+ } else {
+ self.input.text = line;
+ break;
+ }
+ }
+ } else if (self->demo_lines!=NULL && [text isEqual:@"quit"]) {
+ [self unloadDemo];
+ } else {
+ [self appendTape:text tag:@"expr"];
+ NSString *expr = [text stringByAppendingString:@"\n"];
+ NSError *err;
+ NSString *result = MobileEval(expr, &err);
+ if (err != nil) {
+ result = err.description;
+ }
+ result = [result
+ stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
+ result =
+ [result stringByReplacingOccurrencesOfString:@"<" withString:@"&lt;"];
+ result =
+ [result stringByReplacingOccurrencesOfString:@">" withString:@"&gt;"];
+ NSMutableArray *lines =
+ (NSMutableArray *)[result componentsSeparatedByString:@"\n"];
+ for (NSMutableString *line in lines) {
+ if ([line hasPrefix:@"#"])
+ [self appendTape:line tag:@"comment"];
+ else
+ [self appendTape:line tag:@"result"];
+ }
+ self.input.text = @"";
+ }
}

- (void)scrollTapeToBottom
@@ -174,11 +198,46 @@
[self.tape evaluateJavaScript:scroll completionHandler:nil];
}

-- (void)appendTape:(NSString *)text
+- (void)appendTape:(NSString *)text tag:(NSString *)tag
{
- NSString *injectSrc = @"appendDiv('%@');";
- NSString *runToInject = [NSString stringWithFormat:injectSrc, text];
+ NSString *injectSrc = @"appendDiv('%@','%@');";
+ NSString *runToInject = [NSString stringWithFormat:injectSrc, text, tag];
[self.tape evaluateJavaScript:runToInject completionHandler:nil];
+ [self scrollTapeToBottom];
}

+- (void)loadDemo
+{
+ [self.okButton setHidden:FALSE];
+ NSString *text = DemoText();
+
+ self->demo_lines = [text componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
+ self->demo_index = 0;
+ self.input.text = @"";
+ [self enterPressed];
+}
+- (void)unloadDemo
+{
+ [self.okButton setHidden:TRUE];
+ self->demo_lines=NULL;
+ self.input.text = @"";
+}
+- (IBAction)okPressed:(id)sender {
+ [self enterPressed];
+}
+
+- (IBAction)demo:(id)sender {
+ if (self->demo_lines) { // demo already running
+ [self enterPressed];
+ } else {
+ [self loadDemo];
+ }
+}
+
+- (IBAction)clear:(id)sender {
+ [self unloadDemo];
+ NSString *string = [NSString stringWithContentsOfFile:[[NSBundle mainBundle]
+ pathForResource:@"tape" ofType:@"html"] encoding:NSUTF8StringEncoding error:NULL];
+ [self.tape loadHTMLString:string baseURL:NULL];
+}
@end
diff --git a/example/ivy/ios/ivy/tape.html b/example/ivy/ios/ivy/tape.html
index 4b9c796..7340e90 100644
--- a/example/ivy/ios/ivy/tape.html
+++ b/example/ivy/ios/ivy/tape.html
@@ -5,40 +5,56 @@
-->
<html>
<head>
-<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'>
-<style>
-body {
- padding: 0;
- margin: 0;
- margin-top: 20px;
- font-family: Menlo, monospace;
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" charset="UTF-8">
+ <style>
+ body {
+ font-family: sans-serif;
+ }
+ div {
+ padding: 1;
+ white-space: pre-wrap;
+ font-family: "Roboto Mono", monospace;
+ }
+ .comment {
+ color: grey;
+ }
+ .expr {
+ font-weight: bold;
+ }
+ .flow-hide {
+ text-overflow: ellipsis;
+ word-break: break-all;
+ white-space: nowrap;
+ overflow: hidden;
+ }
+ .flow-show {
+ word-break: break-all;
+ }
+ </style>
+
+ <script>
+
+function flowClick(el) {
+ el.classList.toggle("flow-hide");
+ el.classList.toggle("flow-show");
}

-.flowhide {
- text-overflow: ellipsis;
- word-break: break-word;
- overflow-wrap: break-word;
+function appendDiv(txt, tag) {
+ var el = document.createElement("div");
+ el.innerHTML = txt;
+ if (tag == "comment") {
+ el.classList.add("comment");
+ } else if (tag == "expr") {
+ el.classList.add("expr");
+ } else {
+ el.classList.add("flow-show");
+ el.onclick = function() {
+ flowClick(el);
+ };
+ }
+ document.body.appendChild(el);
}

-.flowshow {
- word-break: break-all;
-}
-</style>
-<script>
-function flowclick(el) {
- el.classList.toggle("flowhide");
- el.classList.toggle("flowshow");
-}
-function appendDiv(text) {
- var el = document.createElement("div");
- el.classList.add("flowhide");
- el.innerHTML = text;
- el.onclick = function() {
- flowclick(el);
- };
- document.body.appendChild(el);
- window.scrollBy(0, document.body.offsetHeight);
-}
</script>
<body>
</body>

To view, visit change 357977. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: mobile
Gerrit-Branch: master
Gerrit-Change-Id: I0e853cab102e34053ecdb17edb99644aa2f8651a
Gerrit-Change-Number: 357977
Gerrit-PatchSet: 14
Gerrit-Owner: Robert Engels <ren...@ix.netcom.com>
Gerrit-Reviewer: Go Bot <go...@golang.org>
Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
Gerrit-Reviewer: Peter Weinberger <p...@google.com>
Gerrit-Reviewer: Rob Pike <r...@golang.org>
Gerrit-MessageType: merged
Reply all
Reply to author
Forward
0 new messages