Merge branch 'develop' of https://github.com/CatchChat/Yep into develop

This commit is contained in:
kevinzhow
2015-10-30 19:11:59 +08:00
8 changed files with 277 additions and 102 deletions
+8
View File
@@ -244,6 +244,8 @@
50DEE02D1BE209FF00015741 /* DeletedFeedConversationCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 50DEE02B1BE209FF00015741 /* DeletedFeedConversationCell.xib */; };
50DEE0311BE339B000015741 /* LoadMoreTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50DEE02F1BE339B000015741 /* LoadMoreTableViewCell.swift */; };
50DEE0321BE339B000015741 /* LoadMoreTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 50DEE0301BE339B000015741 /* LoadMoreTableViewCell.xib */; };
50DEE0361BE3720F00015741 /* LoadMoreCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50DEE0341BE3720F00015741 /* LoadMoreCollectionViewCell.swift */; };
50DEE0371BE3720F00015741 /* LoadMoreCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 50DEE0351BE3720F00015741 /* LoadMoreCollectionViewCell.xib */; };
50E114F41ABBF9CC00F13000 /* Models.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E114F31ABBF9CC00F13000 /* Models.swift */; };
50E114F91ABC137A00F13000 /* YepServiceSync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E114F81ABC137A00F13000 /* YepServiceSync.swift */; };
50E114FC1ABC549300F13000 /* ContactsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E114FA1ABC549300F13000 /* ContactsCell.swift */; };
@@ -559,6 +561,8 @@
50DEE02B1BE209FF00015741 /* DeletedFeedConversationCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = DeletedFeedConversationCell.xib; path = Views/Cells/DeletedFeedConversation/DeletedFeedConversationCell.xib; sourceTree = "<group>"; };
50DEE02F1BE339B000015741 /* LoadMoreTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LoadMoreTableViewCell.swift; path = Views/Cells/LoadMore/LoadMoreTableViewCell.swift; sourceTree = "<group>"; };
50DEE0301BE339B000015741 /* LoadMoreTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = LoadMoreTableViewCell.xib; path = Views/Cells/LoadMore/LoadMoreTableViewCell.xib; sourceTree = "<group>"; };
50DEE0341BE3720F00015741 /* LoadMoreCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LoadMoreCollectionViewCell.swift; path = Views/Cells/LoadMore/LoadMoreCollectionViewCell.swift; sourceTree = "<group>"; };
50DEE0351BE3720F00015741 /* LoadMoreCollectionViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = LoadMoreCollectionViewCell.xib; path = Views/Cells/LoadMore/LoadMoreCollectionViewCell.xib; sourceTree = "<group>"; };
50E114F31ABBF9CC00F13000 /* Models.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Models.swift; path = Realm/Models.swift; sourceTree = "<group>"; };
50E114F81ABC137A00F13000 /* YepServiceSync.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = YepServiceSync.swift; path = Services/YepServiceSync.swift; sourceTree = "<group>"; };
50E114FA1ABC549300F13000 /* ContactsCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ContactsCell.swift; path = Views/Cells/Contacts/ContactsCell.swift; sourceTree = "<group>"; };
@@ -1858,6 +1862,8 @@
children = (
50DEE02F1BE339B000015741 /* LoadMoreTableViewCell.swift */,
50DEE0301BE339B000015741 /* LoadMoreTableViewCell.xib */,
50DEE0341BE3720F00015741 /* LoadMoreCollectionViewCell.swift */,
50DEE0351BE3720F00015741 /* LoadMoreCollectionViewCell.xib */,
);
name = LoadMore;
sourceTree = "<group>";
@@ -2248,6 +2254,7 @@
50E1CE8F1BE0BFF00025B933 /* MediaViewCell.xib in Resources */,
505EC8181ADF8151001D27E0 /* SkillCategoryCell.xib in Resources */,
6A8215091BCBE8F10011F36C /* DiscoverSkillCell.xib in Resources */,
50DEE0371BE3720F00015741 /* LoadMoreCollectionViewCell.xib in Resources */,
505EC81D1ADFBE1B001D27E0 /* SkillSelectionCell.xib in Resources */,
50EB8CC01AE89ED8001AC1EE /* ChatLeftVideoCell.xib in Resources */,
50894D0D1AEE0177000981AF /* EditProfileColoredTitleCell.xib in Resources */,
@@ -2497,6 +2504,7 @@
5099B9C71AB99F7B002F940B /* RegisterPickAvatarViewController.swift in Sources */,
50E1CE8E1BE0BFF00025B933 /* MediaViewCell.swift in Sources */,
50DEE0311BE339B000015741 /* LoadMoreTableViewCell.swift in Sources */,
50DEE0361BE3720F00015741 /* LoadMoreCollectionViewCell.swift in Sources */,
504F41251ACE2D1D00FBB19A /* SampleView.swift in Sources */,
50A640EC1B6F4E420050E4A3 /* DoNotDisturbPeriodViewController.swift in Sources */,
502AE5291AB81076005BD199 /* YepService.swift in Sources */,
+2 -2
View File
@@ -356,7 +356,7 @@
</navigationItem>
<connections>
<outlet property="activityIndicator" destination="zzD-ES-eHf" id="ysT-DA-Krf"/>
<outlet property="discoverCollectionView" destination="qiv-cC-3J3" id="4Jx-QJ-kkT"/>
<outlet property="discoveredUsersCollectionView" destination="qiv-cC-3J3" id="Uyg-VP-ENL"/>
<outlet property="filterButtonItem" destination="mve-O6-ube" id="379-Fa-dSw"/>
<outlet property="modeButtonItem" destination="Q6P-X5-laI" id="AMy-5a-IsW"/>
<segue destination="AyC-pt-NR2" kind="show" identifier="showProfile" id="l4P-ds-ihU"/>
@@ -1943,7 +1943,7 @@
<image name="yep_icon_solo" width="120" height="120"/>
</resources>
<inferredMetricsTieBreakers>
<segue reference="WEi-uo-nf5"/>
<segue reference="l4P-ds-ihU"/>
<segue reference="Sdt-ox-uOm"/>
<segue reference="j1h-7M-vYS"/>
</inferredMetricsTieBreakers>
+5 -3
View File
@@ -1176,7 +1176,7 @@ let parseDiscoveredUser: JSONDictionary -> DiscoveredUser? = { userInfo in
let parseDiscoveredUsers: JSONDictionary -> [DiscoveredUser]? = { data in
//println("discoverUsers: \(data)")
println("discoverUsers: \(data)")
if let usersData = data["users"] as? [JSONDictionary] {
@@ -1195,12 +1195,14 @@ let parseDiscoveredUsers: JSONDictionary -> [DiscoveredUser]? = { data in
return nil
}
func discoverUsers(masterSkillIDs masterSkillIDs: [String], learningSkillIDs: [String], discoveredUserSortStyle: DiscoveredUserSortStyle, failureHandler: ((Reason, String?) -> Void)?, completion: [DiscoveredUser] -> Void) {
func discoverUsers(masterSkillIDs masterSkillIDs: [String], learningSkillIDs: [String], discoveredUserSortStyle: DiscoveredUserSortStyle, inPage page: Int, withPerPage perPage: Int, failureHandler: ((Reason, String?) -> Void)?, completion: [DiscoveredUser] -> Void) {
let requestParameters: [String: AnyObject] = [
"master_skills": masterSkillIDs,
"learning_skills": learningSkillIDs,
"sort": discoveredUserSortStyle.rawValue
"sort": discoveredUserSortStyle.rawValue,
"page": page,
"per_page": perPage,
]
let parse = parseDiscoveredUsers
@@ -12,13 +12,13 @@ class DiscoverFlowLayout: UICollectionViewFlowLayout {
var userMode: DiscoverUserMode?
override func prepareLayout() {
switch userMode! {
case .Normal:
self.itemSize = CGSize(width: collectionView!.frame.width, height: 80)
case .Card:
self.itemSize = CGSize(width: (collectionView!.frame.width - (10 + 10 + 10))/2.0, height: 280)
}
}
// override func prepareLayout() {
// switch userMode! {
// case .Normal:
// self.itemSize = CGSize(width: collectionView!.frame.width, height: 80)
// case .Card:
// self.itemSize = CGSize(width: (collectionView!.frame.width - (10 + 10 + 10))/2.0, height: 280)
// }
// }
}
@@ -17,7 +17,7 @@ var skillSizeCache = [String: CGRect]()
class DiscoverViewController: BaseViewController {
@IBOutlet weak var discoverCollectionView: UICollectionView!
@IBOutlet weak var discoveredUsersCollectionView: UICollectionView!
@IBOutlet weak var filterButtonItem: UIBarButtonItem!
@@ -26,8 +26,8 @@ class DiscoverViewController: BaseViewController {
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
let NormalUserIdentifier = "DiscoverNormalUserCell"
let CardUserIdentifier = "DiscoverCardUserCell"
let loadMoreCollectionViewCellID = "LoadMoreCollectionViewCell"
var userMode: DiscoverUserMode = .Card {
didSet {
@@ -43,7 +43,7 @@ class DiscoverViewController: BaseViewController {
}
layout.userMode = userMode
discoverCollectionView.reloadData()
discoveredUsersCollectionView.reloadData()
}
}
@@ -51,46 +51,12 @@ class DiscoverViewController: BaseViewController {
var discoveredUserSortStyle: DiscoveredUserSortStyle = .Default {
didSet {
discoveredUsers = []
discoveredUsersCollectionView.reloadData()
filterButtonItem.title = discoveredUserSortStyle.nameWithArrow
activityIndicator.startAnimating()
view.bringSubviewToFront(activityIndicator)
discoverUsers(masterSkillIDs: [], learningSkillIDs: [], discoveredUserSortStyle: discoveredUserSortStyle, failureHandler: { (reason, errorMessage) in
defaultFailureHandler(reason, errorMessage: errorMessage)
dispatch_async(dispatch_get_main_queue()) { [weak self] in
self?.activityIndicator.stopAnimating()
}
}, completion: { discoveredUsers in
for user in discoveredUsers {
for skill in user.masterSkills {
let skillLocalName = skill.localName ?? ""
let skillID = skill.id
if let _ = skillSizeCache[skillID] {
} else {
let rect = skillLocalName.boundingRectWithSize(CGSize(width: CGFloat(FLT_MAX), height: SkillCell.height), options: [.UsesLineFragmentOrigin, .UsesFontLeading], attributes: skillTextAttributes, context: nil)
skillSizeCache[skillID] = rect
}
}
}
dispatch_async(dispatch_get_main_queue()) { [weak self] in
self?.discoveredUsers = discoveredUsers
self?.activityIndicator.stopAnimating()
}
})
updateDiscoverUsers()
// save discoveredUserSortStyle
@@ -98,16 +64,7 @@ class DiscoverViewController: BaseViewController {
}
}
var discoveredUsers = [DiscoveredUser]() {
willSet {
if newValue.count == 0 {
// discoverCollectionView.tableFooterView = InfoView(NSLocalizedString("No discovered users.", comment: ""))
}
}
didSet {
updateDiscoverTableView()
}
}
var discoveredUsers = [DiscoveredUser]()
lazy var filterView: DiscoverFilterView = DiscoverFilterView()
@@ -130,13 +87,14 @@ class DiscoverViewController: BaseViewController {
discoveredUserSortStyle = .Default
}
discoverCollectionView.backgroundColor = UIColor.clearColor()
discoverCollectionView.setCollectionViewLayout(layout, animated: false)
discoverCollectionView.delegate = self
discoverCollectionView.dataSource = self
discoveredUsersCollectionView.backgroundColor = UIColor.clearColor()
discoveredUsersCollectionView.setCollectionViewLayout(layout, animated: false)
discoveredUsersCollectionView.delegate = self
discoveredUsersCollectionView.dataSource = self
discoverCollectionView.registerNib(UINib(nibName: NormalUserIdentifier, bundle: nil), forCellWithReuseIdentifier: NormalUserIdentifier)
discoverCollectionView.registerNib(UINib(nibName: CardUserIdentifier, bundle: nil), forCellWithReuseIdentifier: CardUserIdentifier)
discoveredUsersCollectionView.registerNib(UINib(nibName: NormalUserIdentifier, bundle: nil), forCellWithReuseIdentifier: NormalUserIdentifier)
discoveredUsersCollectionView.registerNib(UINib(nibName: CardUserIdentifier, bundle: nil), forCellWithReuseIdentifier: CardUserIdentifier)
discoveredUsersCollectionView.registerNib(UINib(nibName: loadMoreCollectionViewCellID, bundle: nil), forCellWithReuseIdentifier: loadMoreCollectionViewCellID)
userMode = .Card
}
@@ -168,11 +126,77 @@ class DiscoverViewController: BaseViewController {
}
}
func updateDiscoverTableView() {
dispatch_async(dispatch_get_main_queue()) {
self.discoverCollectionView.reloadData()
// self.discoverCollectionView.reloadSections(NSIndexSet(index: 0), withRowAnimation: UITableViewRowAnimation.Automatic)
var currentPageIndex = 1
var isFetching = false
func updateDiscoverUsers(isLoadMore isLoadMore: Bool = false, finish: (() -> Void)? = nil) {
if isFetching {
return
}
isFetching = true
if !isLoadMore {
activityIndicator.startAnimating()
view.bringSubviewToFront(activityIndicator)
}
if isLoadMore {
currentPageIndex++
} else {
currentPageIndex = 1
}
discoverUsers(masterSkillIDs: [], learningSkillIDs: [], discoveredUserSortStyle: discoveredUserSortStyle, inPage: currentPageIndex, withPerPage: 30, failureHandler: { (reason, errorMessage) in
defaultFailureHandler(reason, errorMessage: errorMessage)
dispatch_async(dispatch_get_main_queue()) { [weak self] in
self?.activityIndicator.stopAnimating()
self?.isFetching = false
finish?()
}
}, completion: { discoveredUsers in
for user in discoveredUsers {
for skill in user.masterSkills {
let skillLocalName = skill.localName ?? ""
let skillID = skill.id
if let _ = skillSizeCache[skillID] {
} else {
let rect = skillLocalName.boundingRectWithSize(CGSize(width: CGFloat(FLT_MAX), height: SkillCell.height), options: [.UsesLineFragmentOrigin, .UsesFontLeading], attributes: skillTextAttributes, context: nil)
skillSizeCache[skillID] = rect
}
}
}
dispatch_async(dispatch_get_main_queue()) { [weak self] in
if isLoadMore {
self?.discoveredUsers += discoveredUsers
} else {
self?.discoveredUsers = discoveredUsers
}
self?.activityIndicator.stopAnimating()
self?.isFetching = false
finish?()
if !discoveredUsers.isEmpty {
self?.discoveredUsersCollectionView.reloadData()
}
}
})
}
@@ -201,49 +225,137 @@ class DiscoverViewController: BaseViewController {
// MARK: UITableViewDataSource, UITableViewDelegate
extension DiscoverViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
enum Section: Int {
case User
case LoadMore
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 2
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return discoveredUsers.count
switch section {
case Section.User.rawValue:
return discoveredUsers.count
case Section.LoadMore.rawValue:
return discoveredUsers.isEmpty ? 0 : 1
default:
return 0
}
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
switch userMode {
switch indexPath.section {
case .Normal:
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(NormalUserIdentifier, forIndexPath: indexPath) as! DiscoverNormalUserCell
return cell
case .Card:
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(CardUserIdentifier, forIndexPath: indexPath) as! DiscoverCardUserCell
case Section.User.rawValue:
switch userMode {
case .Normal:
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(NormalUserIdentifier, forIndexPath: indexPath) as! DiscoverNormalUserCell
return cell
case .Card:
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(CardUserIdentifier, forIndexPath: indexPath) as! DiscoverCardUserCell
return cell
}
case Section.LoadMore.rawValue:
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(loadMoreCollectionViewCellID, forIndexPath: indexPath) as! LoadMoreCollectionViewCell
return cell
default:
return UICollectionViewCell()
}
}
func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
let discoveredUser = discoveredUsers[indexPath.row]
switch userMode {
case .Normal:
let cell = cell as! DiscoverNormalUserCell
cell.configureWithDiscoveredUser(discoveredUser, collectionView: collectionView, indexPath: indexPath)
case .Card:
let cell = cell as! DiscoverCardUserCell
cell.configureWithDiscoveredUser(discoveredUser, collectionView: collectionView, indexPath: indexPath)
switch indexPath.section {
case Section.User.rawValue:
let discoveredUser = discoveredUsers[indexPath.row]
switch userMode {
case .Normal:
let cell = cell as! DiscoverNormalUserCell
cell.configureWithDiscoveredUser(discoveredUser, collectionView: collectionView, indexPath: indexPath)
case .Card:
let cell = cell as! DiscoverCardUserCell
cell.configureWithDiscoveredUser(discoveredUser, collectionView: collectionView, indexPath: indexPath)
}
case Section.LoadMore.rawValue:
if let cell = cell as? LoadMoreCollectionViewCell {
println("load more discovered users")
if !cell.loadingActivityIndicator.isAnimating() {
cell.loadingActivityIndicator.startAnimating()
}
updateDiscoverUsers(isLoadMore: true, finish: { [weak cell] in
cell?.loadingActivityIndicator.stopAnimating()
})
}
default:
break
}
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
switch indexPath.section {
case Section.User.rawValue:
switch userMode {
case .Normal:
return CGSize(width: UIScreen.mainScreen().bounds.width, height: 80)
case .Card:
return CGSize(width: (UIScreen.mainScreen().bounds.width - (10 + 10 + 10)) * 0.5, height: 280)
}
case Section.LoadMore.rawValue:
return CGSize(width: UIScreen.mainScreen().bounds.width, height: 80)
default:
return CGSizeZero
}
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
switch userMode {
switch section {
case .Normal:
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
case .Card:
return UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
case Section.User.rawValue:
switch userMode {
case .Normal:
return UIEdgeInsetsZero
case .Card:
return UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
}
case Section.LoadMore.rawValue:
return UIEdgeInsetsZero
default:
return UIEdgeInsetsZero
}
}
@@ -328,7 +328,7 @@ class SkillHomeViewController: BaseViewController {
activityIndicator.startAnimating()
discoverUsers(masterSkillIDs: [skillID], learningSkillIDs: [], discoveredUserSortStyle: .Default, failureHandler: { [weak self] (reason, errorMessage) in
discoverUsers(masterSkillIDs: [skillID], learningSkillIDs: [], discoveredUserSortStyle: .Default, inPage: 1, withPerPage: 30, failureHandler: { [weak self] (reason, errorMessage) in
defaultFailureHandler(reason, errorMessage: errorMessage)
dispatch_async(dispatch_get_main_queue()) {
@@ -342,7 +342,7 @@ class SkillHomeViewController: BaseViewController {
}
})
discoverUsers(masterSkillIDs: [], learningSkillIDs: [skillID], discoveredUserSortStyle: .Default, failureHandler: { [weak self] (reason, errorMessage) in
discoverUsers(masterSkillIDs: [], learningSkillIDs: [skillID], discoveredUserSortStyle: .Default, inPage: 1, withPerPage: 30, failureHandler: { [weak self] (reason, errorMessage) in
defaultFailureHandler(reason, errorMessage: errorMessage)
dispatch_async(dispatch_get_main_queue()) {
@@ -0,0 +1,20 @@
//
// LoadMoreCollectionViewCell.swift
// Yep
//
// Created by nixzhu on 15/10/30.
// Copyright © 2015 Catch Inc. All rights reserved.
//
import UIKit
class LoadMoreCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var loadingActivityIndicator: UIActivityIndicatorView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
}
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9059" systemVersion="14F27" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9049"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="LoadMoreCollectionViewCell" id="gTV-IL-0wX" customClass="LoadMoreCollectionViewCell" customModule="Yep" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="155" height="82"/>
<autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="155" height="82"/>
<subviews>
<activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="U29-p5-0bP">
<rect key="frame" x="67" y="31" width="20" height="20"/>
</activityIndicatorView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<constraints>
<constraint firstItem="U29-p5-0bP" firstAttribute="centerY" secondItem="gTV-IL-0wX" secondAttribute="centerY" id="LIX-Pd-q8h"/>
<constraint firstItem="U29-p5-0bP" firstAttribute="centerX" secondItem="gTV-IL-0wX" secondAttribute="centerX" id="mxn-61-s5u"/>
</constraints>
<size key="customSize" width="155" height="82"/>
<connections>
<outlet property="loadingActivityIndicator" destination="U29-p5-0bP" id="caI-ff-htH"/>
</connections>
<point key="canvasLocation" x="276.5" y="223"/>
</collectionViewCell>
</objects>
</document>