mirror of
https://github.com/samsonjs/samhuri.net-ios.git
synced 2026-03-25 09:25:47 +00:00
better UI for adding and removing links in the editor
This commit is contained in:
parent
68b03aedd6
commit
e4c995562e
10 changed files with 140 additions and 69 deletions
|
|
@ -2,6 +2,7 @@
|
|||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7702" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="H1p-Uh-vWS">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
|
||||
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
</dependencies>
|
||||
<customFonts key="customFonts">
|
||||
|
|
@ -57,8 +58,61 @@
|
|||
</items>
|
||||
<color key="barTintColor" red="0.1333333333" green="0.1333333333" blue="0.1333333333" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</toolbar>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="D5w-s5-7oj" userLabel="Link View">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="30"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Link" translatesAutoresizingMaskIntoConstraints="NO" id="VV9-18-i5M">
|
||||
<rect key="frame" x="0.0" y="0.0" width="30" height="30"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" secondItem="VV9-18-i5M" secondAttribute="height" multiplier="1:1" id="vkJ-Ki-XVe"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ydf-ii-P8M">
|
||||
<rect key="frame" x="32" y="1" width="116" height="29"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<state key="normal" title="http://samhuri.net">
|
||||
<color key="titleColor" red="0.96862745098039216" green="0.96862745098039216" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="tappedLinkButton:" destination="JEX-9P-axG" eventType="touchUpInside" id="2Wx-9Z-i8K"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="81X-Pe-PFV">
|
||||
<rect key="frame" x="565" y="0.0" width="30" height="30"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" secondItem="81X-Pe-PFV" secondAttribute="height" multiplier="1:1" id="iW2-b5-VdB"/>
|
||||
</constraints>
|
||||
<inset key="imageEdgeInsets" minX="4" minY="4" maxX="4" maxY="4"/>
|
||||
<state key="normal" image="Close">
|
||||
<color key="titleColor" red="0.96862745100000003" green="0.96862745100000003" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="removeLink:" destination="JEX-9P-axG" eventType="touchUpInside" id="QMx-Rq-EcK"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="centerY" secondItem="ydf-ii-P8M" secondAttribute="centerY" id="0vl-tP-uea"/>
|
||||
<constraint firstAttribute="bottom" secondItem="VV9-18-i5M" secondAttribute="bottom" id="UNh-Jf-v6Z"/>
|
||||
<constraint firstItem="ydf-ii-P8M" firstAttribute="leading" secondItem="VV9-18-i5M" secondAttribute="trailing" constant="2" id="Xsr-b3-oas"/>
|
||||
<constraint firstAttribute="trailing" secondItem="81X-Pe-PFV" secondAttribute="trailing" constant="5" id="YXc-bD-fWD"/>
|
||||
<constraint firstItem="81X-Pe-PFV" firstAttribute="top" secondItem="D5w-s5-7oj" secondAttribute="top" id="due-NH-8Yi"/>
|
||||
<constraint firstAttribute="bottom" secondItem="81X-Pe-PFV" secondAttribute="bottom" id="gJQ-7t-qks"/>
|
||||
<constraint firstItem="VV9-18-i5M" firstAttribute="top" secondItem="D5w-s5-7oj" secondAttribute="top" id="gw5-CW-hQa"/>
|
||||
<constraint firstItem="81X-Pe-PFV" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="ydf-ii-P8M" secondAttribute="trailing" constant="2" id="keD-SD-lgB"/>
|
||||
<constraint firstAttribute="centerY" secondItem="81X-Pe-PFV" secondAttribute="centerY" id="lva-Y3-2ex"/>
|
||||
<constraint firstAttribute="height" constant="30" id="q7G-tD-5zK"/>
|
||||
<constraint firstItem="VV9-18-i5M" firstAttribute="leading" secondItem="D5w-s5-7oj" secondAttribute="leading" id="wvv-Ir-t75"/>
|
||||
</constraints>
|
||||
<variation key="default">
|
||||
<mask key="constraints">
|
||||
<exclude reference="lva-Y3-2ex"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</view>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wrG-1y-ZY3">
|
||||
<rect key="frame" x="0.0" y="25" width="600" height="467"/>
|
||||
<rect key="frame" x="0.0" y="30" width="600" height="462"/>
|
||||
<color key="backgroundColor" red="0.26666666666666666" green="0.26666666666666666" blue="0.26666666666666666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<string key="text">Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda.</string>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
|
|
@ -68,44 +122,35 @@
|
|||
<outlet property="delegate" destination="JEX-9P-axG" id="vKD-HY-lGQ"/>
|
||||
</connections>
|
||||
</textView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="http://samhuri.net" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="UkA-he-S6k">
|
||||
<rect key="frame" x="16" y="4" width="568" height="17"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.1333333333" green="0.1333333333" blue="0.1333333333" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="tintColor" red="0.7953414352" green="0.0" blue="0.013255690590000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="UkA-he-S6k" firstAttribute="leading" secondItem="svH-Pt-448" secondAttribute="leadingMargin" id="1qg-MA-LsX"/>
|
||||
<constraint firstAttribute="width" secondItem="wrG-1y-ZY3" secondAttribute="width" id="8hl-Ab-ACB"/>
|
||||
<constraint firstItem="YUD-Xe-6Cc" firstAttribute="bottom" secondItem="GAO-Cl-Wes" secondAttribute="top" id="DLQ-Z3-h8m"/>
|
||||
<constraint firstAttribute="centerX" secondItem="wrG-1y-ZY3" secondAttribute="centerX" id="FEY-jO-Mjl"/>
|
||||
<constraint firstItem="UkA-he-S6k" firstAttribute="top" secondItem="SYR-Wa-9uf" secondAttribute="bottom" constant="4" id="IFr-2C-sgA"/>
|
||||
<constraint firstAttribute="centerX" secondItem="YUD-Xe-6Cc" secondAttribute="centerX" id="JTh-pp-5hr"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="UkA-he-S6k" secondAttribute="trailing" id="cre-bi-Ah8"/>
|
||||
<constraint firstAttribute="trailing" secondItem="D5w-s5-7oj" secondAttribute="trailing" id="fFI-C6-DCV"/>
|
||||
<constraint firstItem="YUD-Xe-6Cc" firstAttribute="top" secondItem="wrG-1y-ZY3" secondAttribute="bottom" id="iTL-zi-eKI"/>
|
||||
<constraint firstItem="D5w-s5-7oj" firstAttribute="top" secondItem="SYR-Wa-9uf" secondAttribute="bottom" id="lio-NE-qVt"/>
|
||||
<constraint firstAttribute="width" secondItem="YUD-Xe-6Cc" secondAttribute="width" id="n19-6i-zpg"/>
|
||||
<constraint firstItem="wrG-1y-ZY3" firstAttribute="top" secondItem="SYR-Wa-9uf" secondAttribute="bottom" constant="25" id="tUU-ig-gJV"/>
|
||||
<constraint firstItem="D5w-s5-7oj" firstAttribute="leading" secondItem="svH-Pt-448" secondAttribute="leading" id="t3U-SE-qJc"/>
|
||||
<constraint firstItem="wrG-1y-ZY3" firstAttribute="top" secondItem="SYR-Wa-9uf" secondAttribute="bottom" constant="30" id="tUU-ig-gJV"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<toolbarItems/>
|
||||
<navigationItem key="navigationItem" title="Article Title" id="mOI-FS-AaM">
|
||||
<barButtonItem key="backBarButtonItem" title=" " id="KtM-fR-xtg"/>
|
||||
<barButtonItem key="rightBarButtonItem" title="Link" id="tGf-LU-fFC">
|
||||
<connections>
|
||||
<action selector="presentLinkActionSheet:" destination="JEX-9P-axG" id="fuj-e9-dVF"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
<connections>
|
||||
<outlet property="titleView" destination="udr-9h-BhX" id="t9J-lg-ow1"/>
|
||||
</connections>
|
||||
</navigationItem>
|
||||
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics" statusBarStyle="lightContent"/>
|
||||
<connections>
|
||||
<outlet property="linkLabel" destination="UkA-he-S6k" id="Czh-uA-7KF"/>
|
||||
<outlet property="linkButton" destination="ydf-ii-P8M" id="e56-rV-Ztw"/>
|
||||
<outlet property="linkView" destination="D5w-s5-7oj" id="iRD-md-Gea"/>
|
||||
<outlet property="publishBarButtonItem" destination="qEb-VA-ueB" id="biG-Yd-W5Z"/>
|
||||
<outlet property="removeLinkButton" destination="81X-Pe-PFV" id="Rx0-IH-fzp"/>
|
||||
<outlet property="textView" destination="wrG-1y-ZY3" id="lvo-lm-t7Z"/>
|
||||
<outlet property="textViewTopConstraint" destination="tUU-ig-gJV" id="Wzj-Rc-kuM"/>
|
||||
<outlet property="titleView" destination="udr-9h-BhX" id="fju-wx-M92"/>
|
||||
|
|
@ -335,6 +380,10 @@
|
|||
<point key="canvasLocation" x="-45" y="129"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="Close" width="60" height="60"/>
|
||||
<image name="Link" width="67" height="67"/>
|
||||
</resources>
|
||||
<inferredMetricsTieBreakers>
|
||||
<segue reference="6S0-TO-JiA"/>
|
||||
</inferredMetricsTieBreakers>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@
|
|||
@property (nonatomic, weak) IBOutlet UILabel *titleView;
|
||||
@property (nonatomic, weak) IBOutlet UITextView *textView;
|
||||
@property (nonatomic, weak) IBOutlet NSLayoutConstraint *textViewTopConstraint;
|
||||
@property (nonatomic, weak) IBOutlet UILabel *linkLabel;
|
||||
@property (nonatomic, weak) IBOutlet UIView *linkView;
|
||||
@property (nonatomic, weak) IBOutlet UIButton *linkButton;
|
||||
@property (nonatomic, weak) IBOutlet UIButton *removeLinkButton;
|
||||
@property (nonatomic, weak) IBOutlet UIToolbar *toolbar;
|
||||
@property (nonatomic, weak) IBOutlet UIBarButtonItem *publishBarButtonItem;
|
||||
@property (strong, nonatomic) Post *modifiedPost;
|
||||
|
|
@ -52,20 +54,22 @@
|
|||
|
||||
- (void)configureLinkView {
|
||||
NSURL *url = self.modifiedPost.url;
|
||||
if (url) {
|
||||
self.linkLabel.text = url.absoluteString;
|
||||
self.linkLabel.alpha = 0;
|
||||
[UIView animateWithDuration:0.3 animations:^{
|
||||
self.linkLabel.alpha = 1;
|
||||
self.textViewTopConstraint.constant = CGRectGetMaxY(self.linkLabel.frame) + 4;
|
||||
}];
|
||||
if (url || [self pasteboardHasLink]) {
|
||||
NSString *title = url ? url.absoluteString : @"Add Link from Pasteboard";
|
||||
[self.linkButton setTitle:title forState:UIControlStateNormal];
|
||||
self.removeLinkButton.hidden = !url;
|
||||
if (self.textViewTopConstraint.constant <= FLT_EPSILON) {
|
||||
self.linkView.alpha = 0;
|
||||
[UIView animateWithDuration:0.3 animations:^{
|
||||
self.linkView.alpha = 1;
|
||||
self.textViewTopConstraint.constant = CGRectGetMaxY(self.linkView.frame);
|
||||
}];
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (self.textViewTopConstraint.constant > FLT_EPSILON) {
|
||||
[UIView animateWithDuration:0.3 animations:^{
|
||||
self.linkLabel.alpha = 0;
|
||||
self.linkView.alpha = 0;
|
||||
self.textViewTopConstraint.constant = 0;
|
||||
} completion:^(BOOL finished) {
|
||||
self.linkLabel.text = nil;
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
|
@ -99,6 +103,9 @@
|
|||
- (void)viewWillAppear:(BOOL)animated {
|
||||
[super viewWillAppear:animated];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(savePost) name:UIApplicationWillResignActiveNotification object:nil];
|
||||
if ([self pasteboardHasLink]) {
|
||||
[self configureLinkView];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)viewWillDisappear:(BOOL)animated {
|
||||
|
|
@ -257,51 +264,22 @@
|
|||
|
||||
#pragma mark - Link management
|
||||
|
||||
- (IBAction)presentLinkActionSheet:(id)sender {
|
||||
if (self.presentedViewController) {
|
||||
return;
|
||||
}
|
||||
|
||||
- (IBAction)tappedLinkButton:(id)sender {
|
||||
NSURL *currentURL = self.modifiedPost.url;
|
||||
|
||||
// If nothing to add or remove, then don't present the action sheet.
|
||||
if (!currentURL && ![self pasteboardHasLink]) {
|
||||
[self showAlertWithTitle:@"No Link Found" message:@"Copy a link to the pasteboard to add it."];
|
||||
return;
|
||||
}
|
||||
|
||||
UIAlertController *menuController = [UIAlertController alertControllerWithTitle:nil message:currentURL.absoluteString preferredStyle:UIAlertControllerStyleActionSheet];
|
||||
|
||||
// Cancel
|
||||
[menuController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
}]];
|
||||
|
||||
// Add/Replace from Pasteboard
|
||||
NSString *addVerb = self.modifiedPost.link ? @"Replace" : @"Add";
|
||||
if ([self pasteboardHasLink]) {
|
||||
NSString *title = [NSString stringWithFormat:@"%@ from Pasteboard", addVerb];
|
||||
__weak __typeof__(self) welf = self;
|
||||
[menuController addAction:[UIAlertAction actionWithTitle:title style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
|
||||
__typeof__(self) self = welf;
|
||||
[self dismissViewControllerAnimated:YES completion:^{
|
||||
[self addLinkFromPasteboard];
|
||||
}];
|
||||
}]];
|
||||
}
|
||||
|
||||
// Remove Link
|
||||
if (currentURL) {
|
||||
__weak __typeof__(self) welf = self;
|
||||
[menuController addAction:[UIAlertAction actionWithTitle:@"Remove Link" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
|
||||
__typeof__(self) self = welf;
|
||||
[self dismissViewControllerAnimated:YES completion:^{
|
||||
[self updatePostURL:nil];
|
||||
}];
|
||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"TODO" message:@"show a web browser" preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"Dismiss" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
}]];
|
||||
[self presentViewController:alertController animated:YES completion:nil];
|
||||
}
|
||||
else {
|
||||
[self addLinkFromPasteboard];
|
||||
}
|
||||
}
|
||||
|
||||
[self presentViewController:menuController animated:YES completion:nil];
|
||||
- (IBAction)removeLink:(id)sender {
|
||||
[self updatePostURL:nil];
|
||||
}
|
||||
|
||||
- (BOOL)pasteboardHasLink {
|
||||
|
|
|
|||
22
Blog/Images.xcassets/Close.imageset/Contents.json
vendored
Normal file
22
Blog/Images.xcassets/Close.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "close-60@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "close-60@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
BIN
Blog/Images.xcassets/Close.imageset/close-60@2x.png
vendored
Normal file
BIN
Blog/Images.xcassets/Close.imageset/close-60@2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 673 B |
BIN
Blog/Images.xcassets/Close.imageset/close-60@3x.png
vendored
Normal file
BIN
Blog/Images.xcassets/Close.imageset/close-60@3x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
22
Blog/Images.xcassets/Link.imageset/Contents.json
vendored
Normal file
22
Blog/Images.xcassets/Link.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"filename" : "link-67@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"filename" : "link-67@3x.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
BIN
Blog/Images.xcassets/Link.imageset/link-67@2x.png
vendored
Normal file
BIN
Blog/Images.xcassets/Link.imageset/link-67@2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 452 B |
BIN
Blog/Images.xcassets/Link.imageset/link-67@3x.png
vendored
Normal file
BIN
Blog/Images.xcassets/Link.imageset/link-67@3x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 698 B |
BIN
close.pxm
Normal file
BIN
close.pxm
Normal file
Binary file not shown.
BIN
link.pxm
Normal file
BIN
link.pxm
Normal file
Binary file not shown.
Loading…
Reference in a new issue