Merge branch 'feature/pick_feed_skill' into develop

This commit is contained in:
nixzhu
2015-10-22 19:02:36 +08:00
14 changed files with 512 additions and 65 deletions
+1 -1
View File
@@ -52,7 +52,7 @@ DEPENDENCIES:
EXTERNAL SOURCES:
MZFayeClient:
:path: "../CatchLib-iOS/MZFayeClient/"
:path: ../CatchLib-iOS/MZFayeClient/
SPEC CHECKSUMS:
1PasswordExtension: 676a216461ffa9189db66541b5a2465e10ae4743
+20
View File
@@ -207,6 +207,7 @@
50A640EA1B6F45FA0050E4A3 /* DoNotDisturbPeriodCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 50A640E81B6F45FA0050E4A3 /* DoNotDisturbPeriodCell.xib */; };
50A640EC1B6F4E420050E4A3 /* DoNotDisturbPeriodViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A640EB1B6F4E420050E4A3 /* DoNotDisturbPeriodViewController.swift */; };
50A820241B969B0F007CD30E /* NSTimeZone+Yep.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A820231B969B0F007CD30E /* NSTimeZone+Yep.swift */; };
50A93A9D1BD8C515007005DB /* FeedSkillPickerItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A93A9C1BD8C515007005DB /* FeedSkillPickerItemView.swift */; settings = {ASSET_TAGS = (); }; };
50A9D44B1ACD37A8000B2599 /* NSFileManager+Yep.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A9D44A1ACD37A8000B2599 /* NSFileManager+Yep.swift */; };
50A9D44E1ACD382B000B2599 /* NSDateTimeAgo.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 50A9D44C1ACD382B000B2599 /* NSDateTimeAgo.bundle */; };
50A9D4511ACD383E000B2599 /* NSDate+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A9D4501ACD383E000B2599 /* NSDate+Extension.swift */; };
@@ -510,6 +511,7 @@
50A640E81B6F45FA0050E4A3 /* DoNotDisturbPeriodCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = DoNotDisturbPeriodCell.xib; path = Views/Cells/DoNotDisturb/DoNotDisturbPeriodCell.xib; sourceTree = "<group>"; };
50A640EB1B6F4E420050E4A3 /* DoNotDisturbPeriodViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DoNotDisturbPeriodViewController.swift; path = ViewControllers/DoNotDisturbPeriod/DoNotDisturbPeriodViewController.swift; sourceTree = "<group>"; };
50A820231B969B0F007CD30E /* NSTimeZone+Yep.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "NSTimeZone+Yep.swift"; path = "Extensions/NSTimeZone+Yep.swift"; sourceTree = "<group>"; };
50A93A9C1BD8C515007005DB /* FeedSkillPickerItemView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FeedSkillPickerItemView.swift; path = Views/PickerItems/FeedSkill/FeedSkillPickerItemView.swift; sourceTree = "<group>"; };
50A9D44A1ACD37A8000B2599 /* NSFileManager+Yep.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "NSFileManager+Yep.swift"; path = "Extensions/NSFileManager+Yep.swift"; sourceTree = "<group>"; };
50A9D44C1ACD382B000B2599 /* NSDateTimeAgo.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = NSDateTimeAgo.bundle; path = Extensions/NSDateTimeAgo.bundle; sourceTree = "<group>"; };
50A9D4501ACD383E000B2599 /* NSDate+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "NSDate+Extension.swift"; path = "Extensions/NSDate+Extension.swift"; sourceTree = "<group>"; };
@@ -994,6 +996,7 @@
50AACEC91BB54132004DD54B /* Feed */,
50F5AF891BBBB2B30033C9BC /* HorizontalLine */,
50535D1B1BCD19B4002FE1A4 /* TouchClosures */,
50A93A9E1BD8C51D007005DB /* PickerItems */,
);
name = Views;
sourceTree = "<group>";
@@ -1676,6 +1679,22 @@
name = DoNotDisturbPeriod;
sourceTree = "<group>";
};
50A93A9E1BD8C51D007005DB /* PickerItems */ = {
isa = PBXGroup;
children = (
50A93A9F1BD8C52C007005DB /* FeedSkill */,
);
name = PickerItems;
sourceTree = "<group>";
};
50A93A9F1BD8C52C007005DB /* FeedSkill */ = {
isa = PBXGroup;
children = (
50A93A9C1BD8C515007005DB /* FeedSkillPickerItemView.swift */,
);
name = FeedSkill;
sourceTree = "<group>";
};
50A9D4581ACD3943000B2599 /* AudioWaves */ = {
isa = PBXGroup;
children = (
@@ -2450,6 +2469,7 @@
84385C441B8592120071130D /* ShowStepGeniusViewController.swift in Sources */,
6A5632931BC911CB00397B53 /* DiscoverNormalUserCell.swift in Sources */,
5053AD5A1AF83B4200B3CBFA /* ChatLeftLocationCell.swift in Sources */,
50A93A9D1BD8C515007005DB /* FeedSkillPickerItemView.swift in Sources */,
50A640E91B6F45FA0050E4A3 /* DoNotDisturbPeriodCell.swift in Sources */,
502B605A1BD1102B00D9C17E /* TitleCell.swift in Sources */,
840CD23C1B7B59D5000D2680 /* ShowStepViewController.swift in Sources */,
@@ -0,0 +1,12 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "feed_skill_channel_arrow.pdf"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "skill_bubble_empty.pdf",
"resizing" : {
"mode" : "3-part-horizontal",
"center" : {
"mode" : "tile",
"width" : 1
},
"cap-insets" : {
"right" : 11,
"left" : 11
}
}
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
+33 -19
View File
@@ -178,6 +178,31 @@ struct Skill: Hashable {
var hashValue: Int {
return id.hashValue
}
static func fromJSONDictionary(skillInfo: JSONDictionary) -> Skill? {
if
let skillID = skillInfo["id"] as? String,
let skillName = skillInfo["name"] as? String,
let skillLocalName = skillInfo["name_string"] as? String {
var skillCategory: SkillCategory?
if
let skillCategoryData = skillInfo["category"] as? JSONDictionary,
let categoryID = skillCategoryData["id"] as? String,
let categoryName = skillCategoryData["name"] as? String,
let categoryLocalName = skillCategoryData["name_string"] as? String {
skillCategory = SkillCategory(id: categoryID, name: categoryName, localName: categoryLocalName, skills: [])
}
let coverURLString = skillInfo["cover_url"] as? String
let skill = Skill(category: skillCategory, id: skillID, name: skillName, localName: skillLocalName, coverURLString: coverURLString)
return skill
}
return nil
}
}
func ==(lhs: Skill, rhs: Skill) -> Bool {
@@ -222,25 +247,9 @@ func skillsFromSkillsData(skillsData: [JSONDictionary]) -> [Skill] {
var skills = [Skill]()
for skillInfo in skillsData {
if
let skillID = skillInfo["id"] as? String,
let skillName = skillInfo["name"] as? String,
let skillLocalName = skillInfo["name_string"] as? String {
var skillCategory: SkillCategory?
if
let skillCategoryData = skillInfo["category"] as? JSONDictionary,
let categoryID = skillCategoryData["id"] as? String,
let categoryName = skillCategoryData["name"] as? String,
let categoryLocalName = skillCategoryData["name_string"] as? String {
skillCategory = SkillCategory(id: categoryID, name: categoryName, localName: categoryLocalName, skills: [])
}
let coverURLString = skillInfo["cover_url"] as? String
let skill = Skill(category: skillCategory, id: skillID, name: skillName, localName: skillLocalName, coverURLString: coverURLString)
skills.append(skill)
if let skill = Skill.fromJSONDictionary(skillInfo) {
skills.append(skill)
}
}
@@ -2300,7 +2309,12 @@ struct DiscoveredFeed: Hashable {
let attachments = attachmentsData.map({ DiscoveredAttachment.fromJSONDictionary($0) }).flatMap({ $0 })
return DiscoveredFeed(id: id, allowComment: allowComment, createdUnixTime: createdUnixTime, updatedUnixTime: updatedUnixTime, creator: creator, body: body, attachments: attachments, distance: distance, skill: nil, groupID: groupID, messageCount: messageCount)
var skill: Skill?
if let skillInfo = json["skill"] as? JSONDictionary {
skill = Skill.fromJSONDictionary(skillInfo)
}
return DiscoveredFeed(id: id, allowComment: allowComment, createdUnixTime: createdUnixTime, updatedUnixTime: updatedUnixTime, creator: creator, body: body, attachments: attachments, distance: distance, skill: skill, groupID: groupID, messageCount: messageCount)
}
}
+146 -36
View File
@@ -17,55 +17,161 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="nqc-gK-NZL">
<rect key="frame" x="0.0" y="115" width="375" height="80"/>
<animations/>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3C2-gM-yy4">
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="tdd-kc-O7L">
<rect key="frame" x="0.0" y="20" width="375" height="200"/>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</view>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="kWS-hy-hsK">
<rect key="frame" x="15" y="40" width="345" height="60"/>
<animations/>
<constraints>
<constraint firstAttribute="height" constant="60" id="I5A-Wd-eMC"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
<connections>
<outlet property="delegate" destination="qLB-nJ-bBk" id="QVB-4k-Kez"/>
</connections>
</textView>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="nqc-gK-NZL">
<rect key="frame" x="0.0" y="120" width="375" height="80"/>
<animations/>
<constraints>
<constraint firstAttribute="height" constant="80" id="rBg-4C-s5H"/>
</constraints>
<collectionViewFlowLayout key="collectionViewLayout" scrollDirection="horizontal" minimumLineSpacing="10" minimumInteritemSpacing="10" id="EJB-VM-0EX">
<size key="itemSize" width="50" height="50"/>
<size key="headerReferenceSize" width="0.0" height="0.0"/>
<size key="footerReferenceSize" width="0.0" height="0.0"/>
<inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
</collectionViewFlowLayout>
<cells/>
</collectionView>
<pickerView contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="VPy-FV-QI7">
<rect key="frame" x="0.0" y="250" width="375" height="216"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<connections>
<outlet property="dataSource" destination="qLB-nJ-bBk" id="3eu-pm-WCF"/>
<outlet property="delegate" destination="qLB-nJ-bBk" id="rDG-Dy-Q9G"/>
</connections>
</pickerView>
<view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ZQs-7j-O7u">
<rect key="frame" x="0.0" y="328" width="375" height="60"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bhf-Gx-s8P" customClass="HorizontalLineView" customModule="Yep" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="375" height="1"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="o8c-OQ-XAP"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="zRC-QC-BYc" customClass="HorizontalLineView" customModule="Yep" customModuleProvider="target">
<rect key="frame" x="0.0" y="59" width="375" height="1"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="XCb-4Q-ZrJ"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Channel:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="LCK-Ex-Wiz" userLabel="Channel Label">
<rect key="frame" x="20" y="20" width="67.5" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Choose..." textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="u0q-HA-dLM">
<rect key="frame" x="262" y="20" width="73" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="feed_skill_channel_arrow" translatesAutoresizingMaskIntoConstraints="NO" id="BWR-Ne-5Ho">
<rect key="frame" x="350" y="21" width="10" height="18"/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="skill_bubble" translatesAutoresizingMaskIntoConstraints="NO" id="L4w-fH-Iq6">
<rect key="frame" x="280" y="18" width="55" height="24"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Swift" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="J1K-rH-Dph">
<rect key="frame" x="290" y="21" width="35" height="18"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="J1K-rH-Dph" secondAttribute="trailing" constant="50" id="3H4-rv-cv5"/>
<constraint firstItem="L4w-fH-Iq6" firstAttribute="centerY" secondItem="J1K-rH-Dph" secondAttribute="centerY" id="3ic-re-K4g"/>
<constraint firstAttribute="height" constant="60" id="4iB-li-VBX"/>
<constraint firstItem="bhf-Gx-s8P" firstAttribute="top" secondItem="ZQs-7j-O7u" secondAttribute="top" id="9KT-68-Oc7"/>
<constraint firstItem="BWR-Ne-5Ho" firstAttribute="centerY" secondItem="ZQs-7j-O7u" secondAttribute="centerY" id="C0b-4M-smg"/>
<constraint firstItem="LCK-Ex-Wiz" firstAttribute="centerY" secondItem="ZQs-7j-O7u" secondAttribute="centerY" id="Lwh-Zk-2cc"/>
<constraint firstItem="u0q-HA-dLM" firstAttribute="centerY" secondItem="ZQs-7j-O7u" secondAttribute="centerY" id="MVl-sD-1Os"/>
<constraint firstAttribute="trailing" secondItem="u0q-HA-dLM" secondAttribute="trailing" constant="40" id="W6h-GP-mJ8"/>
<constraint firstItem="bhf-Gx-s8P" firstAttribute="leading" secondItem="ZQs-7j-O7u" secondAttribute="leading" id="Y8O-5h-9GY"/>
<constraint firstItem="LCK-Ex-Wiz" firstAttribute="leading" secondItem="ZQs-7j-O7u" secondAttribute="leading" constant="20" id="enR-AE-XD6"/>
<constraint firstItem="L4w-fH-Iq6" firstAttribute="trailing" secondItem="J1K-rH-Dph" secondAttribute="trailing" constant="10" id="gbF-B1-eMJ"/>
<constraint firstAttribute="trailing" secondItem="zRC-QC-BYc" secondAttribute="trailing" id="hDE-VV-K2R"/>
<constraint firstAttribute="trailing" secondItem="BWR-Ne-5Ho" secondAttribute="trailing" constant="15" id="ijD-Lv-deS"/>
<constraint firstItem="zRC-QC-BYc" firstAttribute="leading" secondItem="ZQs-7j-O7u" secondAttribute="leading" id="joi-PN-IA8"/>
<constraint firstAttribute="bottom" secondItem="zRC-QC-BYc" secondAttribute="bottom" id="mvV-X2-Og9"/>
<constraint firstAttribute="trailing" secondItem="bhf-Gx-s8P" secondAttribute="trailing" id="n5P-0j-stA"/>
<constraint firstItem="J1K-rH-Dph" firstAttribute="centerY" secondItem="ZQs-7j-O7u" secondAttribute="centerY" id="nyH-uS-UJt"/>
<constraint firstItem="L4w-fH-Iq6" firstAttribute="leading" secondItem="J1K-rH-Dph" secondAttribute="leading" constant="-10" id="wFA-GI-oKI"/>
</constraints>
</view>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="80" id="rBg-4C-s5H"/>
<constraint firstAttribute="bottom" secondItem="VPy-FV-QI7" secondAttribute="bottom" constant="171" id="HIf-SY-8BI"/>
<constraint firstItem="nqc-gK-NZL" firstAttribute="bottom" secondItem="tdd-kc-O7L" secondAttribute="bottom" constant="-20" id="JYb-6X-tEr"/>
<constraint firstAttribute="trailing" secondItem="VPy-FV-QI7" secondAttribute="trailing" id="Nvv-Mo-16T"/>
<constraint firstItem="VPy-FV-QI7" firstAttribute="top" secondItem="tdd-kc-O7L" secondAttribute="bottom" constant="30" id="StV-TW-ieH"/>
<constraint firstItem="nqc-gK-NZL" firstAttribute="top" secondItem="kWS-hy-hsK" secondAttribute="bottom" constant="20" id="ZYr-tC-BWT"/>
<constraint firstItem="kWS-hy-hsK" firstAttribute="top" secondItem="tdd-kc-O7L" secondAttribute="top" constant="20" id="giF-kr-tIA"/>
<constraint firstItem="tdd-kc-O7L" firstAttribute="top" secondItem="3C2-gM-yy4" secondAttribute="top" constant="20" id="uAi-0N-VVf"/>
<constraint firstItem="ZQs-7j-O7u" firstAttribute="top" secondItem="tdd-kc-O7L" secondAttribute="bottom" constant="108" id="udB-Df-yxg"/>
</constraints>
<collectionViewFlowLayout key="collectionViewLayout" scrollDirection="horizontal" minimumLineSpacing="10" minimumInteritemSpacing="10" id="EJB-VM-0EX">
<size key="itemSize" width="50" height="50"/>
<size key="headerReferenceSize" width="0.0" height="0.0"/>
<size key="footerReferenceSize" width="0.0" height="0.0"/>
<inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
</collectionViewFlowLayout>
<cells/>
</collectionView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="tdd-kc-O7L">
<rect key="frame" x="0.0" y="0.0" width="375" height="210"/>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</view>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="kWS-hy-hsK">
<rect key="frame" x="15" y="35" width="345" height="60"/>
<animations/>
<constraints>
<constraint firstAttribute="height" constant="60" id="I5A-Wd-eMC"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
<connections>
<outlet property="delegate" destination="qLB-nJ-bBk" id="uaS-Dk-w6j"/>
</connections>
</scrollView>
</subviews>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="nqc-gK-NZL" secondAttribute="trailing" id="9aV-hx-aoj"/>
<constraint firstAttribute="trailing" secondItem="tdd-kc-O7L" secondAttribute="trailing" id="ET6-Wp-sPs"/>
<constraint firstItem="tdd-kc-O7L" firstAttribute="bottom" secondItem="nqc-gK-NZL" secondAttribute="bottom" constant="15" id="Euq-y9-NSv"/>
<constraint firstItem="tdd-kc-O7L" firstAttribute="top" secondItem="XTF-TD-X10" secondAttribute="top" id="HYS-Mm-PNs"/>
<constraint firstItem="nqc-gK-NZL" firstAttribute="leading" secondItem="XTF-TD-X10" secondAttribute="leading" id="be1-Wt-Njn"/>
<constraint firstItem="kWS-hy-hsK" firstAttribute="top" secondItem="P6L-c6-EtM" secondAttribute="bottom" constant="15" id="dKw-0O-6Mx"/>
<constraint firstItem="tdd-kc-O7L" firstAttribute="leading" secondItem="XTF-TD-X10" secondAttribute="leading" id="gkg-5n-b4m"/>
<constraint firstItem="nqc-gK-NZL" firstAttribute="top" secondItem="kWS-hy-hsK" secondAttribute="bottom" constant="20" id="lP3-le-51b"/>
<constraint firstItem="kWS-hy-hsK" firstAttribute="leading" secondItem="XTF-TD-X10" secondAttribute="leading" constant="15" id="mNE-5D-ygq"/>
<constraint firstAttribute="trailing" secondItem="kWS-hy-hsK" secondAttribute="trailing" constant="15" id="mgZ-OL-1ch"/>
<constraint firstAttribute="trailing" secondItem="tdd-kc-O7L" secondAttribute="trailing" id="2Tl-EF-rbv"/>
<constraint firstAttribute="trailing" secondItem="kWS-hy-hsK" secondAttribute="trailing" constant="15" id="65Z-BE-tu5"/>
<constraint firstItem="ntq-Pl-HIt" firstAttribute="top" secondItem="3C2-gM-yy4" secondAttribute="bottom" id="9rP-at-xTn"/>
<constraint firstItem="tdd-kc-O7L" firstAttribute="leading" secondItem="XTF-TD-X10" secondAttribute="leading" id="FSf-AM-GwE"/>
<constraint firstItem="3C2-gM-yy4" firstAttribute="leading" secondItem="XTF-TD-X10" secondAttribute="leading" id="Qhy-09-CCo"/>
<constraint firstItem="VPy-FV-QI7" firstAttribute="leading" secondItem="XTF-TD-X10" secondAttribute="leading" id="ZeB-lS-cgJ"/>
<constraint firstAttribute="trailing" secondItem="nqc-gK-NZL" secondAttribute="trailing" id="hAm-q7-cUz"/>
<constraint firstAttribute="trailing" secondItem="3C2-gM-yy4" secondAttribute="trailing" id="jOi-sT-6ef"/>
<constraint firstItem="nqc-gK-NZL" firstAttribute="leading" secondItem="XTF-TD-X10" secondAttribute="leading" id="ln7-A0-SoC"/>
<constraint firstItem="kWS-hy-hsK" firstAttribute="leading" secondItem="XTF-TD-X10" secondAttribute="leading" constant="15" id="old-Li-bBa"/>
<constraint firstItem="3C2-gM-yy4" firstAttribute="top" secondItem="P6L-c6-EtM" secondAttribute="bottom" id="s6A-FW-1V5"/>
<constraint firstAttribute="trailing" secondItem="VPy-FV-QI7" secondAttribute="trailing" id="si5-LX-zVh"/>
<constraint firstItem="ZQs-7j-O7u" firstAttribute="leading" secondItem="XTF-TD-X10" secondAttribute="leading" id="wF2-sQ-Kq6"/>
<constraint firstAttribute="trailing" secondItem="ZQs-7j-O7u" secondAttribute="trailing" id="zI7-0U-fSh"/>
</constraints>
</view>
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina47"/>
<connections>
<outlet property="channelLabel" destination="LCK-Ex-Wiz" id="F2U-PW-esE"/>
<outlet property="channelView" destination="ZQs-7j-O7u" id="TmW-9o-Uu3"/>
<outlet property="channelViewBottomLineView" destination="zRC-QC-BYc" id="mSe-Lh-8Tt"/>
<outlet property="channelViewTopConstraint" destination="udB-Df-yxg" id="o4W-Bo-O5Y"/>
<outlet property="channelViewTopLineView" destination="bhf-Gx-s8P" id="YE9-Yh-t2K"/>
<outlet property="choosePromptLabel" destination="u0q-HA-dLM" id="GcT-Az-ayT"/>
<outlet property="feedWhiteBGView" destination="tdd-kc-O7L" id="32E-RO-YcU"/>
<outlet property="mediaCollectionView" destination="nqc-gK-NZL" id="vUb-KN-uL1"/>
<outlet property="messageTextView" destination="kWS-hy-hsK" id="r5G-r3-3P5"/>
<outlet property="pickedSkillBubbleImageView" destination="L4w-fH-Iq6" id="Qgg-ch-Bcl"/>
<outlet property="pickedSkillLabel" destination="J1K-rH-Dph" id="9JL-5f-f4O"/>
<outlet property="skillPickerView" destination="VPy-FV-QI7" id="Q9U-n1-OyP"/>
<segue destination="frk-9a-m7E" kind="show" identifier="showPickPhotos" id="Bg2-Jr-e9C"/>
</connections>
</viewController>
@@ -82,4 +188,8 @@
<point key="canvasLocation" x="648" y="405"/>
</scene>
</scenes>
<resources>
<image name="feed_skill_channel_arrow" width="10" height="18"/>
<image name="skill_bubble" width="26" height="24"/>
</resources>
</document>
@@ -7,20 +7,35 @@
//
import UIKit
import Proposer
import CoreLocation
import MobileCoreServices
import Photos
import Proposer
import RealmSwift
class NewFeedViewController: UIViewController {
@IBOutlet weak var feedWhiteBGView: UIView!
var afterCreatedFeedAction: ((feed: DiscoveredFeed) -> Void)?
@IBOutlet weak var feedWhiteBGView: UIView!
@IBOutlet weak var messageTextView: UITextView!
@IBOutlet weak var mediaCollectionView: UICollectionView!
@IBOutlet weak var channelView: UIView!
@IBOutlet weak var channelViewTopConstraint: NSLayoutConstraint!
@IBOutlet weak var channelViewTopLineView: HorizontalLineView!
@IBOutlet weak var channelViewBottomLineView: HorizontalLineView!
@IBOutlet weak var channelLabel: UILabel!
@IBOutlet weak var choosePromptLabel: UILabel!
@IBOutlet weak var pickedSkillBubbleImageView: UIImageView!
@IBOutlet weak var pickedSkillLabel: UILabel!
@IBOutlet weak var skillPickerView: UIPickerView!
var imageAssets: [PHAsset] = []
var mediaImages = [UIImage]() {
@@ -34,6 +49,27 @@ class NewFeedViewController: UIViewController {
let feedMediaAddCellID = "FeedMediaAddCell"
let feedMediaCellID = "FeedMediaCell"
let max = Int(INT16_MAX)
let skills: [Skill] = {
if let
myUserID = YepUserDefaults.userID.value,
realm = try? Realm(),
me = userWithUserID(myUserID, inRealm: realm) {
return skillsFromUserSkillList(me.masterSkills) + skillsFromUserSkillList(me.learningSkills)
}
return []
}()
var pickedSkill: Skill? {
willSet {
pickedSkillLabel.text = newValue?.localName
choosePromptLabel.hidden = (newValue != nil)
}
}
override func viewDidLoad() {
super.viewDidLoad()
@@ -53,7 +89,7 @@ class NewFeedViewController: UIViewController {
messageTextView.text = ""
messageTextView.textContainer.lineFragmentPadding = 0
messageTextView.textContainerInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
messageTextView.becomeFirstResponder()
//messageTextView.becomeFirstResponder()
mediaCollectionView.backgroundColor = UIColor.clearColor()
@@ -63,6 +99,23 @@ class NewFeedViewController: UIViewController {
mediaCollectionView.dataSource = self
mediaCollectionView.delegate = self
// pick skill
channelLabel.text = NSLocalizedString("Channel:", comment: "")
choosePromptLabel.text = NSLocalizedString("Choose...", comment: "")
channelViewTopConstraint.constant = 30
skillPickerView.alpha = 0
pickedSkillBubbleImageView.alpha = 0
pickedSkillLabel.alpha = 0
channelView.backgroundColor = UIColor.whiteColor()
channelView.userInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: "showSkillPickerView:")
channelView.addGestureRecognizer(tap)
// try turn on location
let locationResource = PrivateResource.Location(.WhenInUse)
@@ -106,8 +159,62 @@ class NewFeedViewController: UIViewController {
// MARK: Actions
func showSkillPickerView(tap: UITapGestureRecognizer) {
if pickedSkill == nil {
if !skills.isEmpty {
let centerRow = max / 2
skillPickerView.selectRow(centerRow, inComponent: 0, animated: false)
pickedSkill = skills[centerRow % skills.count]
}
}
UIView.animateWithDuration(0.25, delay: 0.0, options: .CurveEaseInOut, animations: { [weak self] in
self?.channelView.backgroundColor = UIColor.clearColor()
self?.channelViewTopLineView.alpha = 0
self?.channelViewBottomLineView.alpha = 0
self?.choosePromptLabel.alpha = 0
self?.pickedSkillBubbleImageView.alpha = 0
self?.pickedSkillLabel.alpha = 0
self?.skillPickerView.alpha = 1
self?.channelViewTopConstraint.constant = 108
self?.view.layoutIfNeeded()
}, completion: { [weak self] _ in
self?.channelView.userInteractionEnabled = false
})
}
func hideSkillPickerView() {
UIView.animateWithDuration(0.25, delay: 0.0, options: .CurveEaseInOut, animations: { [weak self] in
self?.channelView.backgroundColor = UIColor.whiteColor()
self?.channelViewTopLineView.alpha = 1
self?.channelViewBottomLineView.alpha = 1
self?.choosePromptLabel.alpha = 1
self?.pickedSkillBubbleImageView.alpha = 1
self?.pickedSkillLabel.alpha = 1
self?.skillPickerView.alpha = 0
self?.channelViewTopConstraint.constant = 30
self?.view.layoutIfNeeded()
}, completion: { [weak self] _ in
self?.channelView.userInteractionEnabled = true
})
}
func cancel(sender: UIBarButtonItem) {
messageTextView.resignFirstResponder()
self.dismissViewControllerAnimated(true, completion: nil)
}
@@ -148,7 +255,7 @@ class NewFeedViewController: UIViewController {
}
})
dispatch_group_notify(uploadMediaImagesGroup, dispatch_get_main_queue()) {
dispatch_group_notify(uploadMediaImagesGroup, dispatch_get_main_queue()) { [weak self] in
var mediaInfo: JSONDictionary?
@@ -166,7 +273,7 @@ class NewFeedViewController: UIViewController {
]
}
createFeedWithMessage(message, attachments: mediaInfo, coordinate: coordinate, skill: nil, allowComment: true, failureHandler: { [weak self] reason, errorMessage in
createFeedWithMessage(message, attachments: mediaInfo, coordinate: coordinate, skill: self?.pickedSkill, allowComment: true, failureHandler: { [weak self] reason, errorMessage in
defaultFailureHandler(reason, errorMessage: errorMessage)
YepAlert.alertSorry(message: errorMessage ?? NSLocalizedString("Create feed failed!", comment: ""), inViewController: self)
@@ -263,3 +370,61 @@ extension NewFeedViewController: UICollectionViewDataSource, UICollectionViewDel
}
}
// MARK: - UIScrollViewDelegate
extension NewFeedViewController: UITextViewDelegate {
func textViewDidBeginEditing(textView: UITextView) {
hideSkillPickerView()
}
}
// MARK: - UIScrollViewDelegate
extension NewFeedViewController: UIScrollViewDelegate {
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
messageTextView.resignFirstResponder()
}
}
// MARK: - UIPickerViewDataSource, UIPickerViewDelegate
extension NewFeedViewController: UIPickerViewDataSource, UIPickerViewDelegate {
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return skills.isEmpty ? 0 : 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return max
}
func pickerView(pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
return 44
}
func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView?) -> UIView {
let skill = skills[row % skills.count]
if let view = view as? FeedSkillPickerItemView {
view.configureWithSkill(skill)
return view
} else {
let view = FeedSkillPickerItemView()
view.configureWithSkill(skill)
return view
}
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
pickedSkill = skills[row % skills.count]
}
}
+14
View File
@@ -13,6 +13,8 @@ class FeedCell: UITableViewCell {
@IBOutlet weak var avatarImageView: UIImageView!
@IBOutlet weak var nicknameLabel: UILabel!
@IBOutlet weak var distanceLabel: UILabel!
@IBOutlet weak var skillBubbleImageView: UIImageView!
@IBOutlet weak var skillLabel: UILabel!
@IBOutlet weak var messageTextView: FeedTextView!
@IBOutlet weak var messageTextViewHeightConstraint: NSLayoutConstraint!
@@ -78,6 +80,7 @@ class FeedCell: UITableViewCell {
distanceLabel.textColor = UIColor.grayColor()
timeLabel.textColor = UIColor.grayColor()
messageCountLabel.textColor = UIColor.yepTintColor()
skillLabel.textColor = UIColor.yepTintColor()
messageTextView.font = UIFont.feedMessageFont()
messageTextView.textContainer.lineFragmentPadding = 0
@@ -144,6 +147,17 @@ class FeedCell: UITableViewCell {
calHeightOfMessageTextView()
if let skill = feed.skill {
skillLabel.text = skill.localName
skillBubbleImageView.hidden = false
skillLabel.hidden = false
} else {
skillBubbleImageView.hidden = true
skillLabel.hidden = true
}
let hasMedia = !feed.attachments.isEmpty
if feed.attachments.count > 1 {
+20 -3
View File
@@ -43,7 +43,7 @@
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="icon_discussion" translatesAutoresizingMaskIntoConstraints="NO" id="B9B-Nc-h8k">
<rect key="frame" x="333" y="182" width="30" height="19"/>
<rect key="frame" x="336" y="182" width="30" height="19"/>
<animations/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="GRs-kP-Ugk" userLabel="Avatar Image View">
@@ -61,7 +61,7 @@
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="42" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6k9-TF-Ftd" userLabel="Message Count Label">
<rect key="frame" x="306" y="183" width="17" height="17"/>
<rect key="frame" x="309" y="183" width="17" height="17"/>
<animations/>
<fontDescription key="fontDescription" type="system" weight="light" pointSize="14"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
@@ -76,14 +76,26 @@
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
<dataDetectorType key="dataDetectorTypes" phoneNumber="YES" link="YES" address="YES" calendarEvent="YES"/>
</textView>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="skill_bubble_empty" translatesAutoresizingMaskIntoConstraints="NO" id="WvT-iw-dEo">
<rect key="frame" x="317" y="19" width="49" height="22"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Swift" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1ec-vd-wUU">
<rect key="frame" x="327" y="23" width="29" height="14.5"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<animations/>
<constraints>
<constraint firstItem="uir-A9-aaJ" firstAttribute="leading" secondItem="yFm-kf-Ghp" secondAttribute="trailing" constant="15" id="1RE-Ku-WQU"/>
<constraint firstItem="yFm-kf-Ghp" firstAttribute="leading" secondItem="d97-mK-bJE" secondAttribute="leading" id="4dw-W2-nT9"/>
<constraint firstAttribute="trailing" secondItem="B9B-Nc-h8k" secondAttribute="trailing" constant="17.5" id="5um-0R-Amw"/>
<constraint firstAttribute="trailing" secondItem="1ec-vd-wUU" secondAttribute="trailing" constant="25" id="5Wn-VO-vyC"/>
<constraint firstAttribute="trailing" secondItem="B9B-Nc-h8k" secondAttribute="trailing" constant="15" id="5um-0R-Amw"/>
<constraint firstItem="COt-7F-KVK" firstAttribute="top" secondItem="XYv-cX-YOQ" secondAttribute="bottom" constant="15" id="9J9-YH-c9Y"/>
<constraint firstAttribute="trailing" secondItem="COt-7F-KVK" secondAttribute="trailing" id="AfO-Hm-djL"/>
<constraint firstItem="1ec-vd-wUU" firstAttribute="centerY" secondItem="d97-mK-bJE" secondAttribute="centerY" id="DiT-Gx-hJI"/>
<constraint firstItem="1ec-vd-wUU" firstAttribute="leading" secondItem="WvT-iw-dEo" secondAttribute="leading" constant="10" id="H37-Ps-bKw"/>
<constraint firstItem="XYv-cX-YOQ" firstAttribute="top" secondItem="GRs-kP-Ugk" secondAttribute="bottom" constant="4" id="ISv-4s-Llp"/>
<constraint firstItem="XYv-cX-YOQ" firstAttribute="leading" secondItem="d97-mK-bJE" secondAttribute="leading" id="IxD-gR-ma8"/>
<constraint firstItem="B9B-Nc-h8k" firstAttribute="leading" secondItem="6k9-TF-Ftd" secondAttribute="trailing" constant="10" id="JkX-QS-ZmS"/>
@@ -95,9 +107,11 @@
<constraint firstItem="d97-mK-bJE" firstAttribute="centerY" secondItem="GRs-kP-Ugk" secondAttribute="centerY" id="XVe-o1-zRc"/>
<constraint firstItem="GRs-kP-Ugk" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="10" id="cna-DW-PPM"/>
<constraint firstItem="GRs-kP-Ugk" firstAttribute="width" secondItem="GRs-kP-Ugk" secondAttribute="height" multiplier="1:1" id="eSL-Jv-LjB"/>
<constraint firstItem="WvT-iw-dEo" firstAttribute="centerY" secondItem="1ec-vd-wUU" secondAttribute="centerY" id="qUZ-7m-we3"/>
<constraint firstItem="yFm-kf-Ghp" firstAttribute="top" secondItem="XYv-cX-YOQ" secondAttribute="bottom" constant="103" id="sKd-JT-Af9"/>
<constraint firstItem="GRs-kP-Ugk" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="15" id="tIk-7d-Ux7"/>
<constraint firstItem="COt-7F-KVK" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="uDa-ob-a5U"/>
<constraint firstItem="WvT-iw-dEo" firstAttribute="trailing" secondItem="1ec-vd-wUU" secondAttribute="trailing" constant="10" id="z8V-eX-sXm"/>
</constraints>
</tableViewCellContentView>
<animations/>
@@ -111,6 +125,8 @@
<outlet property="messageTextView" destination="XYv-cX-YOQ" id="2mS-ke-PoR"/>
<outlet property="messageTextViewHeightConstraint" destination="DpP-3J-Ftw" id="nSl-a2-gRm"/>
<outlet property="nicknameLabel" destination="d97-mK-bJE" id="xcQ-hs-iRs"/>
<outlet property="skillBubbleImageView" destination="WvT-iw-dEo" id="NjY-at-yj6"/>
<outlet property="skillLabel" destination="1ec-vd-wUU" id="Fa7-yj-SnH"/>
<outlet property="timeLabel" destination="yFm-kf-Ghp" id="Uph-sR-xxS"/>
<outlet property="timeLabelTopConstraint" destination="sKd-JT-Af9" id="fsT-Jb-Ro7"/>
</connections>
@@ -119,5 +135,6 @@
</objects>
<resources>
<image name="icon_discussion" width="30" height="19"/>
<image name="skill_bubble_empty" width="23" height="22"/>
</resources>
</document>
@@ -0,0 +1,64 @@
//
// FeedSkillPickerItemView.swift
// Yep
//
// Created by nixzhu on 15/10/22.
// Copyright © 2015 Catch Inc. All rights reserved.
//
import UIKit
class FeedSkillPickerItemView: UIView {
lazy var bubbleImageView: UIImageView = {
let view = UIImageView(image: UIImage(named: "skill_bubble")!)
return view
}()
lazy var skillLabel: UILabel = {
let label = UILabel()
label.font = UIFont.systemFontOfSize(15)
label.textColor = UIColor.whiteColor()
return label
}()
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
makeUI()
}
override init(frame: CGRect) {
super.init(frame: frame)
makeUI()
}
private func makeUI() {
addSubview(bubbleImageView)
bubbleImageView.translatesAutoresizingMaskIntoConstraints = false
addSubview(skillLabel)
skillLabel.translatesAutoresizingMaskIntoConstraints = false
let skillLabelCenterY = NSLayoutConstraint(item: skillLabel, attribute: .CenterY, relatedBy: .Equal, toItem: self, attribute: .CenterY, multiplier: 1, constant: 0)
let skillLabelTrailing = NSLayoutConstraint(item: skillLabel, attribute: .Trailing, relatedBy: .Equal, toItem: self, attribute: .Trailing, multiplier: 1, constant: -50)
NSLayoutConstraint.activateConstraints([skillLabelCenterY, skillLabelTrailing])
let bubbleImageViewCenterY = NSLayoutConstraint(item: bubbleImageView, attribute: .CenterY, relatedBy: .Equal, toItem: self, attribute: .CenterY, multiplier: 1, constant: 0)
let bubbleImageViewLeading = NSLayoutConstraint(item: bubbleImageView, attribute: .Leading, relatedBy: .Equal, toItem: skillLabel, attribute: .Leading, multiplier: 1, constant: -10)
let bubbleImageViewTrailing = NSLayoutConstraint(item: bubbleImageView, attribute: .Trailing, relatedBy: .Equal, toItem: skillLabel, attribute: .Trailing, multiplier: 1, constant: 10)
NSLayoutConstraint.activateConstraints([bubbleImageViewCenterY, bubbleImageViewLeading, bubbleImageViewTrailing])
}
func configureWithSkill(skill: Skill) {
skillLabel.text = skill.localName
}
}
+4
View File
@@ -636,3 +636,7 @@
"Send Photos (%d)" = "Send Photos (%d)";
"Channel:" = "Channel:";
"Choose..." = "Choose...";
+4
View File
@@ -646,3 +646,7 @@
"Send Photos (%d)" = "发送相片(%d";
"Channel:" = "频道:";
"Choose..." = "选择…";