Mhurd has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/179978

Change subject: Made Nearby use UICollectionView.
......................................................................

Made Nearby use UICollectionView.

Change-Id: I8aa5a50aa21c26deba4b0de752a4e83668f749fa
---
M Wikipedia.xcodeproj/project.pbxproj
M wikipedia/Base.lproj/Main_iPhone.storyboard
A wikipedia/Categories/UICollectionViewCell+DynamicCellHeight.h
A wikipedia/Categories/UICollectionViewCell+DynamicCellHeight.m
D wikipedia/View Controllers/Nearby/NearbyResultCell.xib
R wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.h
R wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.m
A wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.xib
M wikipedia/View Controllers/Nearby/NearbyViewController.h
M wikipedia/View Controllers/Nearby/NearbyViewController.m
10 files changed, 252 insertions(+), 183 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/apps/ios/wikipedia 
refs/changes/78/179978/1

diff --git a/Wikipedia.xcodeproj/project.pbxproj 
b/Wikipedia.xcodeproj/project.pbxproj
index d0b55c8..5857f2f 100644
--- a/Wikipedia.xcodeproj/project.pbxproj
+++ b/Wikipedia.xcodeproj/project.pbxproj
@@ -55,6 +55,9 @@
                04414DDB1A140FAF00A41B4E /* SearchDidYouMeanButton.m in Sources 
*/ = {isa = PBXBuildFile; fileRef = 04414DDA1A140FAF00A41B4E /* 
SearchDidYouMeanButton.m */; };
                04414DDF1A1420EB00A41B4E /* WikiDataShortDescriptionFetcher.m 
in Sources */ = {isa = PBXBuildFile; fileRef = 04414DDE1A1420EB00A41B4E /* 
WikiDataShortDescriptionFetcher.m */; };
                0442F57B19006DCC00F55DF9 /* PageHistoryLabel.m in Sources */ = 
{isa = PBXBuildFile; fileRef = 0442F57A19006DCC00F55DF9 /* PageHistoryLabel.m 
*/; };
+               0443961B1A3C11A30081557D /* NearbyResultCollectionCell.m in 
Sources */ = {isa = PBXBuildFile; fileRef = 0443961A1A3C11A30081557D /* 
NearbyResultCollectionCell.m */; };
+               0443961D1A3C134F0081557D /* NearbyResultCollectionCell.xib in 
Resources */ = {isa = PBXBuildFile; fileRef = 0443961C1A3C134F0081557D /* 
NearbyResultCollectionCell.xib */; };
+               044396231A3D33030081557D /* 
UICollectionViewCell+DynamicCellHeight.m in Sources */ = {isa = PBXBuildFile; 
fileRef = 044396221A3D33030081557D /* UICollectionViewCell+DynamicCellHeight.m 
*/; };
                0447862F185145090050563B /* HistoryResultCell.m in Sources */ = 
{isa = PBXBuildFile; fileRef = 04478621185145090050563B /* HistoryResultCell.m 
*/; };
                04478631185145090050563B /* HistoryResultPrototypeView.xib in 
Resources */ = {isa = PBXBuildFile; fileRef = 04478622185145090050563B /* 
HistoryResultPrototypeView.xib */; };
                04478633185145090050563B /* HistoryViewController.m in Sources 
*/ = {isa = PBXBuildFile; fileRef = 04478624185145090050563B /* 
HistoryViewController.m */; };
@@ -82,14 +85,12 @@
                047528B5191465C400F2CDA8 /* Article.m in Sources */ = {isa = 
PBXBuildFile; fileRef = 047528B4191465C400F2CDA8 /* Article.m */; };
                047801BE18AE987900DBB747 /* UIButton+ColorMask.m in Sources */ 
= {isa = PBXBuildFile; fileRef = 047801BD18AE987900DBB747 /* 
UIButton+ColorMask.m */; };
                047E74141860509000916964 /* SavedPagesResultPrototypeView.xib 
in Resources */ = {isa = PBXBuildFile; fileRef = 047E74131860509000916964 /* 
SavedPagesResultPrototypeView.xib */; };
-               047E95501996DD030046A122 /* NearbyResultCell.m in Sources */ = 
{isa = PBXBuildFile; fileRef = 047E954C1996DD030046A122 /* NearbyResultCell.m 
*/; };
                047E95511996DD030046A122 /* NearbyViewController.m in Sources 
*/ = {isa = PBXBuildFile; fileRef = 047E954E1996DD030046A122 /* 
NearbyViewController.m */; };
                047ED63918C13E4900442BE3 /* PreviewWebView.m in Sources */ = 
{isa = PBXBuildFile; fileRef = 047ED63818C13E4900442BE3 /* PreviewWebView.m */; 
};
                047FF5471889078C009DB293 /* Image+Convenience.m in Sources */ = 
{isa = PBXBuildFile; fileRef = 047FF5461889078C009DB293 /* Image+Convenience.m 
*/; };
                04821CD119895EDC007558F6 /* ReferenceGradientView.m in Sources 
*/ = {isa = PBXBuildFile; fileRef = 04821CD019895EDC007558F6 /* 
ReferenceGradientView.m */; };
                0484411E19FF15AF00FD26C5 /* AboutViewController.plist in 
Resources */ = {isa = PBXBuildFile; fileRef = 0484411D19FF15AF00FD26C5 /* 
AboutViewController.plist */; };
                0484E3DE19D9D19B0085D18D /* UIView+ConstraintsScale.m in 
Sources */ = {isa = PBXBuildFile; fileRef = 0484E3DD19D9D19B0085D18D /* 
UIView+ConstraintsScale.m */; };
-               0485FECF1994D5AE00141361 /* NearbyResultCell.xib in Resources 
*/ = {isa = PBXBuildFile; fileRef = 0485FECD1994D5AE00141361 /* 
NearbyResultCell.xib */; };
                0487041419F7683300B7D307 /* Cocoapods Notes.txt in Resources */ 
= {isa = PBXBuildFile; fileRef = 0487041319F7683300B7D307 /* Cocoapods 
Notes.txt */; };
                0487045519F824D700B7D307 /* QueuesSingleton.m in Sources */ = 
{isa = PBXBuildFile; fileRef = 0487044119F824D700B7D307 /* QueuesSingleton.m 
*/; };
                0487047E19F8262600B7D307 /* AccountCreationTokenFetcher.m in 
Sources */ = {isa = PBXBuildFile; fileRef = 0487045819F8262600B7D307 /* 
AccountCreationTokenFetcher.m */; };
@@ -365,6 +366,11 @@
                04414DDE1A1420EB00A41B4E /* WikiDataShortDescriptionFetcher.m 
*/ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = 
sourcecode.c.objc; path = WikiDataShortDescriptionFetcher.m; sourceTree = 
"<group>"; };
                0442F57919006DCC00F55DF9 /* PageHistoryLabel.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
PageHistoryLabel.h; sourceTree = "<group>"; };
                0442F57A19006DCC00F55DF9 /* PageHistoryLabel.m */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path 
= PageHistoryLabel.m; sourceTree = "<group>"; };
+               044396191A3C11A30081557D /* NearbyResultCollectionCell.h */ = 
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; 
path = NearbyResultCollectionCell.h; sourceTree = "<group>"; };
+               0443961A1A3C11A30081557D /* NearbyResultCollectionCell.m */ = 
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = 
sourcecode.c.objc; path = NearbyResultCollectionCell.m; sourceTree = "<group>"; 
};
+               0443961C1A3C134F0081557D /* NearbyResultCollectionCell.xib */ = 
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = 
NearbyResultCollectionCell.xib; sourceTree = "<group>"; };
+               044396211A3D33030081557D /* 
UICollectionViewCell+DynamicCellHeight.h */ = {isa = PBXFileReference; 
fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
"UICollectionViewCell+DynamicCellHeight.h"; sourceTree = "<group>"; };
+               044396221A3D33030081557D /* 
UICollectionViewCell+DynamicCellHeight.m */ = {isa = PBXFileReference; 
fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = 
"UICollectionViewCell+DynamicCellHeight.m"; sourceTree = "<group>"; };
                04478620185145090050563B /* HistoryResultCell.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
HistoryResultCell.h; sourceTree = "<group>"; };
                04478621185145090050563B /* HistoryResultCell.m */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path 
= HistoryResultCell.m; sourceTree = "<group>"; };
                04478622185145090050563B /* HistoryResultPrototypeView.xib */ = 
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = 
HistoryResultPrototypeView.xib; sourceTree = "<group>"; };
@@ -417,8 +423,6 @@
                047801BC18AE987900DBB747 /* UIButton+ColorMask.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
"UIButton+ColorMask.h"; sourceTree = "<group>"; };
                047801BD18AE987900DBB747 /* UIButton+ColorMask.m */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path 
= "UIButton+ColorMask.m"; sourceTree = "<group>"; };
                047E74131860509000916964 /* SavedPagesResultPrototypeView.xib 
*/ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; 
path = SavedPagesResultPrototypeView.xib; sourceTree = "<group>"; };
-               047E954B1996DD030046A122 /* NearbyResultCell.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
NearbyResultCell.h; sourceTree = "<group>"; };
-               047E954C1996DD030046A122 /* NearbyResultCell.m */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path 
= NearbyResultCell.m; sourceTree = "<group>"; };
                047E954D1996DD030046A122 /* NearbyViewController.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
NearbyViewController.h; sourceTree = "<group>"; };
                047E954E1996DD030046A122 /* NearbyViewController.m */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path 
= NearbyViewController.m; sourceTree = "<group>"; };
                047ED63718C13E4900442BE3 /* PreviewWebView.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
PreviewWebView.h; sourceTree = "<group>"; };
@@ -430,7 +434,6 @@
                0484411D19FF15AF00FD26C5 /* AboutViewController.plist */ = {isa 
= PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path 
= AboutViewController.plist; sourceTree = "<group>"; };
                0484E3DC19D9D19B0085D18D /* UIView+ConstraintsScale.h */ = {isa 
= PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path 
= "UIView+ConstraintsScale.h"; sourceTree = "<group>"; };
                0484E3DD19D9D19B0085D18D /* UIView+ConstraintsScale.m */ = {isa 
= PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; 
path = "UIView+ConstraintsScale.m"; sourceTree = "<group>"; };
-               0485FECD1994D5AE00141361 /* NearbyResultCell.xib */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = 
NearbyResultCell.xib; sourceTree = "<group>"; };
                0487041319F7683300B7D307 /* Cocoapods Notes.txt */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Cocoapods 
Notes.txt"; sourceTree = "<group>"; };
                0487044019F824D700B7D307 /* QueuesSingleton.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
QueuesSingleton.h; sourceTree = "<group>"; };
                0487044119F824D700B7D307 /* QueuesSingleton.m */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path 
= QueuesSingleton.m; sourceTree = "<group>"; };
@@ -1160,11 +1163,11 @@
                        children = (
                                047E954D1996DD030046A122 /* 
NearbyViewController.h */,
                                047E954E1996DD030046A122 /* 
NearbyViewController.m */,
-                               047E954B1996DD030046A122 /* NearbyResultCell.h 
*/,
-                               047E954C1996DD030046A122 /* NearbyResultCell.m 
*/,
-                               0485FECD1994D5AE00141361 /* 
NearbyResultCell.xib */,
                                04D308261998A8AA0034F106 /* 
NearbyThumbnailView.h */,
                                04D308271998A8AA0034F106 /* 
NearbyThumbnailView.m */,
+                               044396191A3C11A30081557D /* 
NearbyResultCollectionCell.h */,
+                               0443961A1A3C11A30081557D /* 
NearbyResultCollectionCell.m */,
+                               0443961C1A3C134F0081557D /* 
NearbyResultCollectionCell.xib */,
                        );
                        path = Nearby;
                        sourceTree = "<group>";
@@ -1443,6 +1446,8 @@
                                04B91AA618E34BBC00FFAA1C /* 
UIView+TemporaryAnimatedXF.m */,
                                043F8BF01A11699A00D1AE44 /* 
UIView+RoundCorners.h */,
                                043F8BF11A11699A00D1AE44 /* 
UIView+RoundCorners.m */,
+                               044396211A3D33030081557D /* 
UICollectionViewCell+DynamicCellHeight.h */,
+                               044396221A3D33030081557D /* 
UICollectionViewCell+DynamicCellHeight.m */,
                                0433542018A023FE009305F0 /* 
UIViewController+HideKeyboard.h */,
                                0433542118A023FE009305F0 /* 
UIViewController+HideKeyboard.m */,
                                0452C80E195D0F03007925A6 /* 
UIViewController+ModalPop.h */,
@@ -1989,7 +1994,7 @@
                                041E588319B2D2C500AC140C /* 
[email protected] in Resources */,
                                04090A33187F53E400577EDF /* clear.png in 
Resources */,
                                0412362E189C29EA00E0CF8E /* 
abuse-filter-disallowed.png in Resources */,
-                               0485FECF1994D5AE00141361 /* 
NearbyResultCell.xib in Resources */,
+                               0443961D1A3C134F0081557D /* 
NearbyResultCollectionCell.xib in Resources */,
                                04082B5518ADA25A00FAF3D6 /* 
[email protected] in Resources */,
                                04C91CF219554B310035ED1B /* logo-onboarding.png 
in Resources */,
                                045A9F0D18F6090E0057EA85 /* assets in Resources 
*/,
@@ -2108,7 +2113,6 @@
                                043F8BEF1A1146B300D1AE44 /* SearchTypeMenu.m in 
Sources */,
                                0487048B19F8262600B7D307 /* 
RandomArticleFetcher.m in Sources */,
                                04D34DBD1863F6A400610A87 /* GalleryImage.m in 
Sources */,
-                               047E95501996DD030046A122 /* NearbyResultCell.m 
in Sources */,
                                042A5B36192591520095E172 /* TopMenuTextField.m 
in Sources */,
                                04AE1C701891B302002D5487 /* NSObject+Extras.m 
in Sources */,
                                04B7B9BD18B5570E00A63551 /* 
CaptchaViewController.m in Sources */,
@@ -2144,12 +2148,14 @@
                                048A26771906268100395F53 /* PaddedLabel.m in 
Sources */,
                                04B91AAB18E3D9E200FFAA1C /* 
NSString+FormattedAttributedString.m in Sources */,
                                043F18E518D9691D00D8489A /* 
UINavigationController+TopActionSheet.m in Sources */,
+                               044396231A3D33030081557D /* 
UICollectionViewCell+DynamicCellHeight.m in Sources */,
                                04414DDF1A1420EB00A41B4E /* 
WikiDataShortDescriptionFetcher.m in Sources */,
                                04D308281998A8AA0034F106 /* 
NearbyThumbnailView.m in Sources */,
                                04292FF2185FBA70002A13FC /* SearchResultCell.m 
in Sources */,
                                04F0E2EA186EDC1A00468738 /* 
UIWebView+ElementLocation.m in Sources */,
                                0447866F1852B5010050563B /* SessionSingleton.m 
in Sources */,
                                D4E8A8A4190835C100DA4765 /* DataMigrator.m in 
Sources */,
+                               0443961B1A3C11A30081557D /* 
NearbyResultCollectionCell.m in Sources */,
                                0487048519F8262600B7D307 /* EditTokenFetcher.m 
in Sources */,
                                04CCCFF71935094000E3F60C /* 
PrimaryMenuTableViewCell.m in Sources */,
                                0487048F19F8262600B7D307 /* 
WikiTextSectionFetcher.m in Sources */,
diff --git a/wikipedia/Base.lproj/Main_iPhone.storyboard 
b/wikipedia/Base.lproj/Main_iPhone.storyboard
index 353417f..5fde453 100644
--- a/wikipedia/Base.lproj/Main_iPhone.storyboard
+++ b/wikipedia/Base.lproj/Main_iPhone.storyboard
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" 
version="3.0" toolsVersion="6250" systemVersion="14B25" 
targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" 
initialViewController="1qV-3k-dN1">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" 
version="3.0" toolsVersion="6254" systemVersion="14B25" 
targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" 
initialViewController="1qV-3k-dN1">
     <dependencies>
         <deployment identifier="iOS"/>
         <development version="5100" identifier="xcode"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" 
version="6244"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" 
version="6247"/>
         <capability name="Alignment constraints with different attributes" 
minToolsVersion="5.1"/>
         <capability name="Constraints to layout margins" 
minToolsVersion="6.0"/>
     </dependencies>
@@ -1484,25 +1484,32 @@
                         <rect key="frame" x="0.0" y="0.0" width="320" 
height="568"/>
                         <autoresizingMask key="autoresizingMask" 
flexibleMaxX="YES" flexibleMaxY="YES"/>
                         <subviews>
-                            <tableView clipsSubviews="YES" 
contentMode="scaleToFill" alwaysBounceVertical="YES" 
showsHorizontalScrollIndicator="NO" dataMode="prototypes" style="plain" 
separatorStyle="none" rowHeight="44" sectionHeaderHeight="22" 
sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" 
id="UNM-cA-smO">
+                            <collectionView clipsSubviews="YES" 
multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" 
translatesAutoresizingMaskIntoConstraints="NO" id="qqE-rv-Duu">
                                 <rect key="frame" x="0.0" y="0.0" width="320" 
height="568"/>
                                 <color key="backgroundColor" white="1" 
alpha="1" colorSpace="calibratedWhite"/>
+                                <collectionViewFlowLayout 
key="collectionViewLayout" minimumLineSpacing="1" minimumInteritemSpacing="1" 
id="aOe-N5-EQS">
+                                    <size key="itemSize" width="320" 
height="160"/>
+                                    <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/>
                                 <connections>
-                                    <outlet property="dataSource" 
destination="O3D-bU-RYB" id="BIW-rD-Jnx"/>
-                                    <outlet property="delegate" 
destination="O3D-bU-RYB" id="DSy-mw-68t"/>
+                                    <outlet property="dataSource" 
destination="O3D-bU-RYB" id="zkO-We-pBj"/>
+                                    <outlet property="delegate" 
destination="O3D-bU-RYB" id="JkI-es-NF6"/>
                                 </connections>
-                            </tableView>
+                            </collectionView>
                         </subviews>
                         <color key="backgroundColor" white="1" alpha="1" 
colorSpace="custom" customColorSpace="calibratedWhite"/>
                         <constraints>
-                            <constraint firstItem="b0O-Y9-uxP" 
firstAttribute="top" secondItem="UNM-cA-smO" secondAttribute="bottom" 
id="IL6-81-CYs"/>
-                            <constraint firstItem="UNM-cA-smO" 
firstAttribute="leading" secondItem="Y20-F2-l6h" secondAttribute="leading" 
id="NDE-yU-BsV"/>
-                            <constraint firstAttribute="trailing" 
secondItem="UNM-cA-smO" secondAttribute="trailing" id="OTa-9i-hcI"/>
-                            <constraint firstItem="UNM-cA-smO" 
firstAttribute="top" secondItem="Y20-F2-l6h" secondAttribute="top" 
id="kpx-2i-aeH"/>
+                            <constraint firstItem="qqE-rv-Duu" 
firstAttribute="leading" secondItem="Y20-F2-l6h" secondAttribute="leading" 
id="41d-fB-oSz"/>
+                            <constraint firstAttribute="bottom" 
secondItem="qqE-rv-Duu" secondAttribute="bottom" id="evF-xJ-ghj"/>
+                            <constraint firstAttribute="trailing" 
secondItem="qqE-rv-Duu" secondAttribute="trailing" id="mz4-n8-VZt"/>
+                            <constraint firstItem="qqE-rv-Duu" 
firstAttribute="top" secondItem="Y20-F2-l6h" secondAttribute="top" 
id="uU5-wT-VX0"/>
                         </constraints>
                     </view>
                     <connections>
-                        <outlet property="tableView" destination="UNM-cA-smO" 
id="1Cr-nz-7Ld"/>
+                        <outlet property="collectionView" 
destination="qqE-rv-Duu" id="dFT-iu-hzE"/>
                     </connections>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" 
id="mef-6q-1qK" userLabel="First Responder" sceneMemberID="firstResponder"/>
diff --git a/wikipedia/Categories/UICollectionViewCell+DynamicCellHeight.h 
b/wikipedia/Categories/UICollectionViewCell+DynamicCellHeight.h
new file mode 100644
index 0000000..fac8b9c
--- /dev/null
+++ b/wikipedia/Categories/UICollectionViewCell+DynamicCellHeight.h
@@ -0,0 +1,10 @@
+//  Created by Monte Hurd on 12/13/14.
+//  Copyright (c) 2014 Wikimedia Foundation. Provided under MIT-style license; 
please copy and modify!
+
+#import <UIKit/UIKit.h>
+
+@interface UICollectionViewCell (DynamicCellHeight)
+
+-(CGFloat)heightForSizingCellOfWidth:(CGFloat)width;
+
+@end
diff --git a/wikipedia/Categories/UICollectionViewCell+DynamicCellHeight.m 
b/wikipedia/Categories/UICollectionViewCell+DynamicCellHeight.m
new file mode 100644
index 0000000..0c6e6dd
--- /dev/null
+++ b/wikipedia/Categories/UICollectionViewCell+DynamicCellHeight.m
@@ -0,0 +1,18 @@
+//  Created by Monte Hurd on 12/13/14.
+//  Copyright (c) 2014 Wikimedia Foundation. Provided under MIT-style license; 
please copy and modify!
+
+#import "UICollectionViewCell+DynamicCellHeight.h"
+
+@implementation UICollectionViewCell (DynamicCellHeight)
+
+-(CGFloat)heightForSizingCellOfWidth:(CGFloat)width
+{
+    [self setNeedsUpdateConstraints];
+    [self updateConstraintsIfNeeded];
+    self.bounds = CGRectMake(0.0f, 0.0f, width, CGRectGetHeight(self.bounds));
+    [self setNeedsLayout];
+    [self layoutIfNeeded];
+    return [self.contentView 
systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height + 1.0f;
+}
+
+@end
diff --git a/wikipedia/View Controllers/Nearby/NearbyResultCell.xib 
b/wikipedia/View Controllers/Nearby/NearbyResultCell.xib
deleted file mode 100644
index 2a9f0d8..0000000
--- a/wikipedia/View Controllers/Nearby/NearbyResultCell.xib
+++ /dev/null
@@ -1,95 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" 
toolsVersion="6250" systemVersion="14B25" targetRuntime="iOS.CocoaTouch" 
propertyAccessControl="none" useAutolayout="YES">
-    <dependencies>
-        <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" 
version="6244"/>
-    </dependencies>
-    <objects>
-        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" 
userLabel="File's Owner"/>
-        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" 
customClass="UIResponder"/>
-        <tableViewCell contentMode="scaleToFill" 
restorationIdentifier="NearbyResultCell" selectionStyle="default" 
indentationWidth="10" reuseIdentifier="NearbyResultCell" rowHeight="170" 
id="KGk-i7-Jjw" customClass="NearbyResultCell">
-            <rect key="frame" x="0.0" y="0.0" width="400" height="170"/>
-            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" 
flexibleMaxY="YES"/>
-            <tableViewCellContentView key="contentView" opaque="NO" 
clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" 
tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
-                <rect key="frame" x="0.0" y="0.0" width="400" height="138"/>
-                <autoresizingMask key="autoresizingMask"/>
-                <subviews>
-                    <view contentMode="scaleToFill" 
translatesAutoresizingMaskIntoConstraints="NO" id="NqR-Qb-IaR" 
customClass="NearbyThumbnailView">
-                        <rect key="frame" x="10" y="33" width="104" 
height="104"/>
-                        <color key="backgroundColor" white="1" alpha="1" 
colorSpace="custom" customColorSpace="calibratedWhite"/>
-                        <constraints>
-                            <constraint firstAttribute="width" constant="104" 
id="OwT-he-KFK"/>
-                            <constraint firstAttribute="height" constant="104" 
id="djl-Na-081"/>
-                        </constraints>
-                    </view>
-                    <view contentMode="scaleToFill" 
translatesAutoresizingMaskIntoConstraints="NO" id="NO1-IN-caZ" userLabel="Text 
Fields Outer Container">
-                        <rect key="frame" x="126" y="6" width="264" 
height="157"/>
-                        <subviews>
-                            <view contentMode="scaleToFill" 
translatesAutoresizingMaskIntoConstraints="NO" id="O1S-6h-g6j" userLabel="Text 
Fields Inner Container">
-                                <rect key="frame" x="0.0" y="34" width="264" 
height="90"/>
-                                <subviews>
-                                    <label opaque="NO" clipsSubviews="YES" 
userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" 
horizontalCompressionResistancePriority="1000" 
verticalCompressionResistancePriority="1000" text="" lineBreakMode="wordWrap" 
numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" 
preferredMaxLayoutWidth="264" translatesAutoresizingMaskIntoConstraints="NO" 
id="MOc-73-Qn8" userLabel="Title" customClass="PaddedLabel">
-                                        <rect key="frame" x="0.0" y="0.0" 
width="264" height="60"/>
-                                        <constraints>
-                                            <constraint 
firstAttribute="height" constant="60" placeholder="YES" id="eIi-uP-p9y"/>
-                                        </constraints>
-                                        <fontDescription key="fontDescription" 
type="system" pointSize="17"/>
-                                        <nil key="highlightedColor"/>
-                                    </label>
-                                    <label opaque="NO" clipsSubviews="YES" 
userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" 
verticalHuggingPriority="251" horizontalCompressionResistancePriority="1000" 
verticalCompressionResistancePriority="1000" text="Distance" 
lineBreakMode="wordWrap" baselineAdjustment="alignBaselines" 
adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" 
id="onP-ym-Gp1" customClass="PaddedLabel">
-                                        <rect key="frame" x="0.0" y="65" 
width="60" height="21"/>
-                                        <constraints>
-                                            <constraint firstAttribute="width" 
constant="60" placeholder="YES" id="ABL-FD-JSV"/>
-                                            <constraint 
firstAttribute="height" constant="21" id="tZw-sO-BHs"/>
-                                        </constraints>
-                                        <fontDescription key="fontDescription" 
type="system" pointSize="13"/>
-                                        <color key="textColor" white="1" 
alpha="1" colorSpace="calibratedWhite"/>
-                                        <nil key="highlightedColor"/>
-                                    </label>
-                                </subviews>
-                                <color key="backgroundColor" white="1" 
alpha="1" colorSpace="calibratedWhite"/>
-                                <constraints>
-                                    <constraint firstItem="onP-ym-Gp1" 
firstAttribute="leading" secondItem="O1S-6h-g6j" secondAttribute="leading" 
id="0Xj-k4-zAN"/>
-                                    <constraint firstAttribute="bottom" 
relation="greaterThanOrEqual" secondItem="onP-ym-Gp1" secondAttribute="bottom" 
id="1ZV-Ul-5FL"/>
-                                    <constraint firstItem="MOc-73-Qn8" 
firstAttribute="leading" secondItem="O1S-6h-g6j" secondAttribute="leading" 
id="28e-1t-892"/>
-                                    <constraint firstAttribute="trailing" 
secondItem="MOc-73-Qn8" secondAttribute="trailing" id="Hoo-97-oCe"/>
-                                    <constraint firstItem="MOc-73-Qn8" 
firstAttribute="top" secondItem="O1S-6h-g6j" secondAttribute="top" 
id="KVX-le-WE4"/>
-                                    <constraint firstItem="onP-ym-Gp1" 
firstAttribute="top" secondItem="MOc-73-Qn8" secondAttribute="bottom" 
constant="5" id="f11-dq-Uav"/>
-                                    <constraint firstAttribute="height" 
constant="90" placeholder="YES" id="l59-Q9-ajD"/>
-                                </constraints>
-                            </view>
-                        </subviews>
-                        <color key="backgroundColor" white="1" alpha="1" 
colorSpace="calibratedWhite"/>
-                        <constraints>
-                            <constraint firstItem="O1S-6h-g6j" 
firstAttribute="top" relation="greaterThanOrEqual" secondItem="NO1-IN-caZ" 
secondAttribute="top" id="LZW-KV-ioA"/>
-                            <constraint firstAttribute="centerY" 
secondItem="O1S-6h-g6j" secondAttribute="centerY" id="Xj9-po-kH7"/>
-                            <constraint firstItem="O1S-6h-g6j" 
firstAttribute="bottom" relation="lessThanOrEqual" secondItem="NO1-IN-caZ" 
secondAttribute="bottom" id="dXl-xg-KMS"/>
-                            <constraint firstItem="O1S-6h-g6j" 
firstAttribute="leading" secondItem="NO1-IN-caZ" secondAttribute="leading" 
id="mbw-f3-fHM"/>
-                            <constraint firstAttribute="trailing" 
secondItem="O1S-6h-g6j" secondAttribute="trailing" id="saT-8x-GTR"/>
-                        </constraints>
-                    </view>
-                </subviews>
-                <constraints>
-                    <constraint firstAttribute="bottom" 
secondItem="NO1-IN-caZ" secondAttribute="bottom" constant="6" id="2qd-FL-Kzh"/>
-                    <constraint firstAttribute="centerY" 
secondItem="NqR-Qb-IaR" secondAttribute="centerY" id="8lL-tV-fBx"/>
-                    <constraint firstAttribute="trailing" 
secondItem="NO1-IN-caZ" secondAttribute="trailing" constant="10" 
id="J7G-J0-8Wa"/>
-                    <constraint firstItem="NqR-Qb-IaR" 
firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" 
constant="10" id="TWI-rp-Isg"/>
-                    <constraint firstItem="NO1-IN-caZ" firstAttribute="height" 
relation="greaterThanOrEqual" secondItem="NqR-Qb-IaR" secondAttribute="height" 
id="Yo2-n9-lNw"/>
-                    <constraint firstItem="NO1-IN-caZ" firstAttribute="top" 
secondItem="H2p-sc-9uM" secondAttribute="top" constant="6" id="qSg-dm-4wW"/>
-                    <constraint firstItem="NO1-IN-caZ" 
firstAttribute="leading" secondItem="NqR-Qb-IaR" secondAttribute="trailing" 
constant="12" id="x6b-B0-vOk"/>
-                </constraints>
-            </tableViewCellContentView>
-            <connections>
-                <outlet property="distanceLabel" destination="onP-ym-Gp1" 
id="ACO-NS-byA"/>
-                <outlet property="thumbView" destination="NqR-Qb-IaR" 
id="xNk-l2-rdN"/>
-                <outlet property="titleLabel" destination="MOc-73-Qn8" 
id="aU6-q4-lIz"/>
-            </connections>
-            <point key="canvasLocation" x="432" y="211"/>
-        </tableViewCell>
-    </objects>
-    <simulatedMetricsContainer key="defaultSimulatedMetrics">
-        <simulatedStatusBarMetrics key="statusBar"/>
-        <simulatedOrientationMetrics key="orientation"/>
-        <simulatedScreenMetrics key="destination" type="retina4"/>
-    </simulatedMetricsContainer>
-</document>
diff --git a/wikipedia/View Controllers/Nearby/NearbyResultCell.h 
b/wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.h
similarity index 70%
rename from wikipedia/View Controllers/Nearby/NearbyResultCell.h
rename to wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.h
index f5b279c..617eaa4 100644
--- a/wikipedia/View Controllers/Nearby/NearbyResultCell.h
+++ b/wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.h
@@ -1,4 +1,4 @@
-//  Created by Monte Hurd on 8/8/14.
+//  Created by Monte Hurd on 12/12/14.
 //  Copyright (c) 2014 Wikimedia Foundation. Provided under MIT-style license; 
please copy and modify!
 
 #import <UIKit/UIKit.h>
@@ -6,15 +6,15 @@
 #import "NearbyThumbnailView.h"
 
 @class PaddedLabel, NearbyArrowView, NearbyThumbnailView;
-@interface NearbyResultCell : UITableViewCell
+@interface NearbyResultCollectionCell : UICollectionViewCell
 
 @property (weak, nonatomic) IBOutlet NearbyThumbnailView *thumbView;
 
 @property (strong, nonatomic) NSNumber *distance;
-@property (strong, nonatomic) CLLocation *location;
-@property (strong, nonatomic) CLLocation *deviceLocation;
+@property (nonatomic) CLLocationCoordinate2D location;
+@property (nonatomic) CLLocationCoordinate2D deviceLocation;
 @property (nonatomic) BOOL headingAvailable;
-@property (strong, nonatomic) CLHeading *deviceHeading;
+@property (nonatomic) CLLocationDirection deviceHeading;
 @property (nonatomic) UIInterfaceOrientation interfaceOrientation;
 
 @property (strong, nonatomic) UILongPressGestureRecognizer 
*longPressRecognizer;
diff --git a/wikipedia/View Controllers/Nearby/NearbyResultCell.m 
b/wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.m
similarity index 81%
rename from wikipedia/View Controllers/Nearby/NearbyResultCell.m
rename to wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.m
index cdedf88..d59130f 100644
--- a/wikipedia/View Controllers/Nearby/NearbyResultCell.m
+++ b/wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.m
@@ -1,7 +1,7 @@
-//  Created by Monte Hurd on 8/8/14.
+//  Created by Monte Hurd on 12/12/14.
 //  Copyright (c) 2014 Wikimedia Foundation. Provided under MIT-style license; 
please copy and modify!
 
-#import "NearbyResultCell.h"
+#import "NearbyResultCollectionCell.h"
 #import "PaddedLabel.h"
 #import "WikipediaAppUtils.h"
 #import "WMF_Colors.h"
@@ -25,7 +25,7 @@
 #define DESCRIPTION_FONT_COLOR [UIColor grayColor]
 #define DESCRIPTION_TOP_PADDING (2.0f * MENUS_SCALE_MULTIPLIER)
 
-@interface NearbyResultCell()
+@interface NearbyResultCollectionCell()
 
 @property (weak, nonatomic) IBOutlet PaddedLabel *distanceLabel;
 @property (weak, nonatomic) IBOutlet PaddedLabel *titleLabel;
@@ -35,7 +35,7 @@
 
 @end
 
-@implementation NearbyResultCell
+@implementation NearbyResultCollectionCell
 
 -(void)setTitle: (NSString *)title
     description: (NSString *)description
@@ -93,9 +93,8 @@
     if (self) {
         self.longPressRecognizer = nil;
         self.distance = nil;
-        self.location = nil;
-        self.deviceLocation = nil;
-        self.selectionStyle = UITableViewCellSelectionStyleNone;
+        self.location = CLLocationCoordinate2DMake(0, 0);
+        self.deviceLocation = CLLocationCoordinate2DMake(0, 0);
     }
     return self;
 }
@@ -162,43 +161,43 @@
     }
 }
 
--(void)setLocation:(CLLocation *)location
+-(void)setLocation:(CLLocationCoordinate2D)location
 {
     _location = location;
     
     [self applyRotationTransform];
 }
 
--(void)setDeviceHeading:(CLHeading *)deviceHeading
+-(void)setDeviceHeading:(CLLocationDirection)deviceHeading
 {
     _deviceHeading = deviceHeading;
 
     [self applyRotationTransform];
 }
 
--(double)headingBetweenLocation:(CLLocation *)l1 andLocation:(CLLocation *)l2
+-(double)headingBetweenLocation: (CLLocationCoordinate2D)loc1
+                    andLocation: (CLLocationCoordinate2D)loc2
 {
     // From: http://www.movable-type.co.uk/scripts/latlong.html
-       double dy = l2.coordinate.longitude - l1.coordinate.longitude;
-       double y = sin(dy) * cos(l2.coordinate.latitude);
-       double x = cos(l1.coordinate.latitude) * sin(l2.coordinate.latitude) - 
sin(l1.coordinate.latitude) * cos(l2.coordinate.latitude) * cos(dy);
+       double dy = loc2.longitude - loc1.longitude;
+       double y = sin(dy) * cos(loc2.latitude);
+       double x = cos(loc1.latitude) * sin(loc2.latitude) - sin(loc1.latitude) 
* cos(loc2.latitude) * cos(dy);
        return atan2(y, x);
 }
 
--(void)applyRotationTransform
+-(double)getAngleFromLocation: (CLLocationCoordinate2D)fromLocation
+                   toLocation: (CLLocationCoordinate2D)toLocation
+             adjustForHeading: (CLLocationDirection)deviceHeading
+         adjustForOrientation: (UIInterfaceOrientation)interfaceOrientation
 {
-    self.thumbView.headingAvailable = self.headingAvailable;
-    if(!self.headingAvailable) return;
-
     // Get angle between device and article coordinates.
-    double angleRadians = [self headingBetweenLocation:self.deviceLocation 
andLocation:self.location];
+    double angleRadians = [self headingBetweenLocation:fromLocation 
andLocation:toLocation];
 
     // Adjust for device rotation (deviceHeading is in degrees).
     double angleDegrees = RADIANS_TO_DEGREES(angleRadians);
-    angleDegrees += 180;
-    angleDegrees -= (self.deviceHeading.trueHeading - 180.0f);
-    if (angleDegrees > 360) angleDegrees -= 360;
-    if (angleDegrees < -360) angleDegrees += 360;
+    angleDegrees -= deviceHeading;
+    if (angleDegrees > 360.0) angleDegrees -= 360.0;
+    if (angleDegrees < -360.0) angleDegrees += 360.0;
 
     /*
     if ([self.titleLabel.text isEqualToString:@"Museum of London"]){
@@ -207,15 +206,15 @@
     */
 
     // Adjust for interface orientation.
-    switch (self.interfaceOrientation) {
+    switch (interfaceOrientation) {
         case UIInterfaceOrientationLandscapeLeft:
-            angleDegrees += 90;
+            angleDegrees += 90.0;
             break;
         case UIInterfaceOrientationLandscapeRight:
-            angleDegrees -= 90;
+            angleDegrees -= 90.0;
             break;
         case UIInterfaceOrientationPortraitUpsideDown:
-            angleDegrees += 180;
+            angleDegrees += 180.0;
             break;
         default: //UIInterfaceOrientationPortrait
             break;
@@ -227,16 +226,30 @@
     }
     */
 
-    angleRadians = DEGREES_TO_RADIANS(angleDegrees);
-
-    [self.thumbView drawTickAtHeading:angleRadians];    
+    return DEGREES_TO_RADIANS(angleDegrees);
 }
 
+-(void)applyRotationTransform
+{
+    self.thumbView.headingAvailable = self.headingAvailable;
+    if(!self.headingAvailable) return;
+
+    double angle =
+        [self getAngleFromLocation: self.deviceLocation
+                        toLocation: self.location
+                  adjustForHeading: self.deviceHeading
+              adjustForOrientation: self.interfaceOrientation];
+
+    [self.thumbView drawTickAtHeading:angle];
+}
+
+/*
 - (void)setSelected:(BOOL)selected animated:(BOOL)animated
 {
     [super setSelected:selected animated:animated];
 
     // Configure the view for the selected state
 }
+*/
 
 @end
diff --git a/wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.xib 
b/wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.xib
new file mode 100644
index 0000000..f2034c2
--- /dev/null
+++ b/wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.xib
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" 
toolsVersion="6254" systemVersion="14B25" targetRuntime="iOS.CocoaTouch" 
propertyAccessControl="none" useAutolayout="YES">
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" 
version="6247"/>
+    </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="NearbyResultCollectionCell" id="ed5-Sf-o8Y" 
customClass="NearbyResultCollectionCell">
+            <rect key="frame" x="0.0" y="0.0" width="400" height="200"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" 
flexibleMaxY="YES"/>
+            <view key="contentView" opaque="NO" clipsSubviews="YES" 
multipleTouchEnabled="YES" contentMode="center">
+                <rect key="frame" x="0.0" y="0.0" width="400" height="200"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <view contentMode="scaleToFill" 
translatesAutoresizingMaskIntoConstraints="NO" id="tu4-KP-F6a" 
customClass="NearbyThumbnailView">
+                        <rect key="frame" x="10" y="48" width="104" 
height="104"/>
+                        <color key="backgroundColor" white="1" alpha="1" 
colorSpace="custom" customColorSpace="calibratedWhite"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="104" 
id="BaE-OF-B19"/>
+                            <constraint firstAttribute="width" constant="104" 
id="Hsx-PJ-PYa"/>
+                        </constraints>
+                    </view>
+                    <view contentMode="scaleToFill" 
translatesAutoresizingMaskIntoConstraints="NO" id="exF-qc-AXF" userLabel="Text 
Fields Outer Container">
+                        <rect key="frame" x="126" y="6" width="264" 
height="188"/>
+                        <subviews>
+                            <view contentMode="scaleToFill" 
translatesAutoresizingMaskIntoConstraints="NO" id="OTu-ke-cDq" userLabel="Text 
Fields Inner Container">
+                                <rect key="frame" x="0.0" y="49" width="264" 
height="90"/>
+                                <subviews>
+                                    <label opaque="NO" clipsSubviews="YES" 
userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" 
horizontalCompressionResistancePriority="1000" 
verticalCompressionResistancePriority="1000" text="" lineBreakMode="wordWrap" 
numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" 
preferredMaxLayoutWidth="264" translatesAutoresizingMaskIntoConstraints="NO" 
id="97x-uE-MIC" userLabel="Title" customClass="PaddedLabel">
+                                        <rect key="frame" x="0.0" y="0.0" 
width="264" height="60"/>
+                                        <constraints>
+                                            <constraint 
firstAttribute="height" constant="60" placeholder="YES" id="UQx-Xq-ytn"/>
+                                        </constraints>
+                                        <fontDescription key="fontDescription" 
type="system" pointSize="17"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <label opaque="NO" clipsSubviews="YES" 
userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" 
verticalHuggingPriority="251" horizontalCompressionResistancePriority="1000" 
verticalCompressionResistancePriority="1000" text="Distance" 
lineBreakMode="wordWrap" baselineAdjustment="alignBaselines" 
adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" 
id="gGV-Kd-65L" customClass="PaddedLabel">
+                                        <rect key="frame" x="0.0" y="65" 
width="60" height="21"/>
+                                        <constraints>
+                                            <constraint 
firstAttribute="height" constant="21" id="Gxs-n2-Zp7"/>
+                                            <constraint firstAttribute="width" 
constant="60" placeholder="YES" id="IYQ-Yz-AO0"/>
+                                        </constraints>
+                                        <fontDescription key="fontDescription" 
type="system" pointSize="13"/>
+                                        <color key="textColor" white="1" 
alpha="1" colorSpace="calibratedWhite"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                </subviews>
+                                <color key="backgroundColor" white="1" 
alpha="1" colorSpace="calibratedWhite"/>
+                                <constraints>
+                                    <constraint firstItem="gGV-Kd-65L" 
firstAttribute="leading" secondItem="OTu-ke-cDq" secondAttribute="leading" 
id="4Ll-8w-mkX"/>
+                                    <constraint firstItem="97x-uE-MIC" 
firstAttribute="leading" secondItem="OTu-ke-cDq" secondAttribute="leading" 
id="Bhu-pE-8c5"/>
+                                    <constraint firstAttribute="bottom" 
relation="greaterThanOrEqual" secondItem="gGV-Kd-65L" secondAttribute="bottom" 
id="Gqx-ca-JLb"/>
+                                    <constraint firstItem="97x-uE-MIC" 
firstAttribute="top" secondItem="OTu-ke-cDq" secondAttribute="top" 
id="Mlu-J5-tAw"/>
+                                    <constraint firstItem="gGV-Kd-65L" 
firstAttribute="top" secondItem="97x-uE-MIC" secondAttribute="bottom" 
constant="5" id="Ovw-yP-Kv6"/>
+                                    <constraint firstAttribute="trailing" 
secondItem="97x-uE-MIC" secondAttribute="trailing" id="TIg-06-5Jl"/>
+                                    <constraint firstAttribute="height" 
constant="90" placeholder="YES" id="xEJ-eu-Joz"/>
+                                </constraints>
+                            </view>
+                        </subviews>
+                        <color key="backgroundColor" white="1" alpha="1" 
colorSpace="calibratedWhite"/>
+                        <constraints>
+                            <constraint firstItem="OTu-ke-cDq" 
firstAttribute="leading" secondItem="exF-qc-AXF" secondAttribute="leading" 
id="7U1-s4-EHT"/>
+                            <constraint firstItem="OTu-ke-cDq" 
firstAttribute="bottom" relation="lessThanOrEqual" secondItem="exF-qc-AXF" 
secondAttribute="bottom" id="8Or-JN-FH8"/>
+                            <constraint firstItem="OTu-ke-cDq" 
firstAttribute="top" relation="greaterThanOrEqual" secondItem="exF-qc-AXF" 
secondAttribute="top" id="RMy-bc-iB5"/>
+                            <constraint firstAttribute="trailing" 
secondItem="OTu-ke-cDq" secondAttribute="trailing" id="c3q-9z-Zsc"/>
+                            <constraint firstAttribute="centerY" 
secondItem="OTu-ke-cDq" secondAttribute="centerY" id="uyl-vG-4MI"/>
+                        </constraints>
+                    </view>
+                </subviews>
+                <color key="backgroundColor" white="0.0" alpha="0.0" 
colorSpace="calibratedWhite"/>
+            </view>
+            <constraints>
+                <constraint firstAttribute="trailing" secondItem="exF-qc-AXF" 
secondAttribute="trailing" constant="10" id="6HK-dL-qgA"/>
+                <constraint firstItem="exF-qc-AXF" firstAttribute="leading" 
secondItem="tu4-KP-F6a" secondAttribute="trailing" constant="12" 
id="AjR-Iy-4UN"/>
+                <constraint firstAttribute="centerY" secondItem="tu4-KP-F6a" 
secondAttribute="centerY" id="BUr-tl-0Gq"/>
+                <constraint firstItem="exF-qc-AXF" firstAttribute="height" 
relation="greaterThanOrEqual" secondItem="tu4-KP-F6a" secondAttribute="height" 
id="Jjm-O4-ENH"/>
+                <constraint firstAttribute="bottom" secondItem="exF-qc-AXF" 
secondAttribute="bottom" constant="6" id="S4h-oJ-xYe"/>
+                <constraint firstItem="exF-qc-AXF" firstAttribute="top" 
secondItem="ed5-Sf-o8Y" secondAttribute="top" constant="6" id="bES-yB-pIH"/>
+                <constraint firstItem="tu4-KP-F6a" firstAttribute="leading" 
secondItem="ed5-Sf-o8Y" secondAttribute="leading" constant="10" 
id="mBs-u7-HT5"/>
+            </constraints>
+            <size key="customSize" width="384" height="192"/>
+            <connections>
+                <outlet property="distanceLabel" destination="gGV-Kd-65L" 
id="wAV-05-nz4"/>
+                <outlet property="thumbView" destination="tu4-KP-F6a" 
id="t8D-HG-vg4"/>
+                <outlet property="titleLabel" destination="97x-uE-MIC" 
id="p0F-9I-6UX"/>
+            </connections>
+            <point key="canvasLocation" x="406" y="233"/>
+        </collectionViewCell>
+    </objects>
+    <simulatedMetricsContainer key="defaultSimulatedMetrics">
+        <simulatedStatusBarMetrics key="statusBar"/>
+        <simulatedOrientationMetrics key="orientation"/>
+        <simulatedScreenMetrics key="destination" type="retina4"/>
+    </simulatedMetricsContainer>
+</document>
diff --git a/wikipedia/View Controllers/Nearby/NearbyViewController.h 
b/wikipedia/View Controllers/Nearby/NearbyViewController.h
index f34c374..a518a46 100644
--- a/wikipedia/View Controllers/Nearby/NearbyViewController.h
+++ b/wikipedia/View Controllers/Nearby/NearbyViewController.h
@@ -7,7 +7,7 @@
 #import "TopMenuViewController.h"
 #import "FetcherBase.h"
 
-@interface NearbyViewController : PullToRefreshViewController 
<UITableViewDataSource, UITableViewDelegate, CLLocationManagerDelegate, 
UIActionSheetDelegate, FetchFinishedDelegate>
+@interface NearbyViewController : PullToRefreshViewController 
<UICollectionViewDataSource, UICollectionViewDelegate, 
CLLocationManagerDelegate, UIActionSheetDelegate, FetchFinishedDelegate>
 
 @property (nonatomic) NavBarMode navBarMode;
 @property (weak, nonatomic) id truePresentingVC;
diff --git a/wikipedia/View Controllers/Nearby/NearbyViewController.m 
b/wikipedia/View Controllers/Nearby/NearbyViewController.m
index 442ff3b..b634f26 100644
--- a/wikipedia/View Controllers/Nearby/NearbyViewController.m
+++ b/wikipedia/View Controllers/Nearby/NearbyViewController.m
@@ -2,7 +2,7 @@
 //  Copyright (c) 2014 Wikimedia Foundation. Provided under MIT-style license; 
please copy and modify!
 
 #import "NearbyViewController.h"
-#import "NearbyResultCell.h"
+#import "NearbyResultCollectionCell.h"
 #import "NearbyFetcher.h"
 #import "ThumbnailFetcher.h"
 #import "QueuesSingleton.h"
@@ -17,14 +17,14 @@
 #import <MapKit/MapKit.h>
 #import "Defines.h"
 #import "NSString+Extras.h"
-#import "UITableView+DynamicCellHeight.h"
+#import "UICollectionViewCell+DynamicCellHeight.h"
 
-#define TABLE_CELL_ID @"NearbyResultCell"
+#define TABLE_CELL_ID @"NearbyResultCollectionCell"
 
 @interface NearbyViewController ()
 
 @property (strong, nonatomic) NSArray *nearbyDataArray;
-@property (strong, nonatomic) IBOutlet UITableView *tableView;
+@property (strong, nonatomic) IBOutlet UICollectionView *collectionView;
 @property (strong, nonatomic) CLLocationManager *locationManager;
 @property (strong, nonatomic) CLLocation *deviceLocation;
 @property (strong, nonatomic) CLHeading *deviceHeading;
@@ -35,7 +35,7 @@
 @property (nonatomic, strong) UIImage *placeholderImage;
 @property (nonatomic, strong) NSString *cachePath;
 @property (nonatomic) BOOL headingAvailable;
-@property (strong, nonatomic) NearbyResultCell *offScreenSizingCell;
+@property (strong, nonatomic) NearbyResultCollectionCell *offScreenSizingCell;
 
 @end
 
@@ -83,7 +83,7 @@
 
 @implementation NearbyViewController
 
-- (void)tableView:(UITableView *)tableView 
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+- (void)collectionView:(UICollectionView *)collectionView 
didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
     NSDictionary *rowData = [self getRowDataForIndexPath:indexPath];
     NSString *title = rowData[@"title"];
     [NAV loadArticleWithTitle: [[SessionSingleton sharedInstance].site 
titleWithString:title]
@@ -194,7 +194,7 @@
 -(void)refresh
 {
     self.nearbyDataArray = @[@[]];
-    [self.tableView reloadData];
+    [self.collectionView reloadData];
     self.refreshNeeded = YES;
     
     // Force an update if we already have location data, else by setting
@@ -207,7 +207,7 @@
 
 -(UIScrollView *)refreshScrollView
 {
-    return self.tableView;
+    return self.collectionView;
 }
 
 -(NSString *)refreshPromptString
@@ -258,7 +258,7 @@
                 NSArray *arraySortedByDistance = [self.nearbyDataArray[0] 
sortedArrayUsingDescriptors:@[sortDescriptor]];
                 self.nearbyDataArray = @[arraySortedByDistance];
                 
-                [self.tableView reloadData];
+                [self.collectionView reloadData];
             }
                 break;
             case FETCH_FINAL_STATUS_CANCELLED:
@@ -286,12 +286,12 @@
                 UIImage *image = [UIImage imageWithData:fetchedData];
                 
                 // Check if cell still onscreen! This is important!
-                NSArray *visibleRowIndexPaths = [self.tableView 
indexPathsForVisibleRows];
+                NSArray *visibleRowIndexPaths = [self.collectionView 
indexPathsForVisibleItems];
                 for (NSIndexPath *thisIndexPath in visibleRowIndexPaths.copy) {
                     NSDictionary *rowData = [self 
getRowDataForIndexPath:thisIndexPath];
                     NSString *url = rowData[@"thumbnail"][@"source"];
                     if ([url.lastPathComponent isEqualToString:fileName]) {
-                        NearbyResultCell *cell = (NearbyResultCell 
*)[self.tableView cellForRowAtIndexPath:thisIndexPath];
+                        NearbyResultCollectionCell *cell = 
(NearbyResultCollectionCell *)[self.collectionView 
cellForItemAtIndexPath:thisIndexPath];
                         [cell.thumbView setImage:image isPlaceHolder:NO];
                         [cell setNeedsDisplay];
                         break;
@@ -345,6 +345,11 @@
     [self updateDistancesForOnscreenCells];
 }
 
+-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
 duration:(NSTimeInterval)duration
+{
+    [self.collectionView.collectionViewLayout invalidateLayout];
+}
+
 - (void)locationManager: (CLLocationManager *)manager
        didUpdateHeading: (CLHeading *)newHeading
 {
@@ -355,10 +360,10 @@
 
 -(void)updateHeadingForOnscreenCells
 {
-    for (NSIndexPath *indexPath in 
self.tableView.indexPathsForVisibleRows.copy){
-        NearbyResultCell *cell = (NearbyResultCell *)[self.tableView 
cellForRowAtIndexPath:indexPath];
+    for (NSIndexPath *indexPath in 
self.collectionView.indexPathsForVisibleItems.copy){
+        NearbyResultCollectionCell *cell = (NearbyResultCollectionCell 
*)[self.collectionView cellForItemAtIndexPath:indexPath];
 
-        cell.deviceHeading = self.deviceHeading;
+        cell.deviceHeading = self.deviceHeading.trueHeading;
 
         [cell setNeedsDisplay];
     }
@@ -366,8 +371,8 @@
 
 -(void)updateDistancesForOnscreenCells
 {
-    for (NSIndexPath *indexPath in 
self.tableView.indexPathsForVisibleRows.copy){
-        NearbyResultCell *cell = (NearbyResultCell *)[self.tableView 
cellForRowAtIndexPath:indexPath];
+    for (NSIndexPath *indexPath in 
self.collectionView.indexPathsForVisibleItems.copy){
+        NearbyResultCollectionCell *cell = (NearbyResultCollectionCell 
*)[self.collectionView cellForItemAtIndexPath:indexPath];
 
         [self updateLocationDataOfCell:cell atIndexPath:indexPath];
 
@@ -409,12 +414,16 @@
         [self.locationManager startUpdatingHeading];
     }
     
-    self.tableView.tableHeaderView = [[UIView alloc] 
initWithFrame:CGRectMake(0, 0, 1, 19)];
+    UICollectionViewFlowLayout *layout =
+        (UICollectionViewFlowLayout*)self.collectionView.collectionViewLayout;
+    CGFloat topAndBottomMargin = 19.0f * MENUS_SCALE_MULTIPLIER;
+    layout.sectionInset = UIEdgeInsetsMake(topAndBottomMargin, 0, 
topAndBottomMargin, 0);
     
-    [self.tableView registerNib:[UINib nibWithNibName:TABLE_CELL_ID 
bundle:nil] forCellReuseIdentifier:TABLE_CELL_ID];
+    [self.collectionView registerNib:[UINib nibWithNibName:TABLE_CELL_ID 
bundle:nil] forCellWithReuseIdentifier:TABLE_CELL_ID];
 
     // Single off-screen cell for determining dynamic cell height.
-    self.offScreenSizingCell = (NearbyResultCell *)[self.tableView 
dequeueReusableCellWithIdentifier:TABLE_CELL_ID];
+    self.offScreenSizingCell =
+        [[[NSBundle mainBundle] loadNibNamed:@"NearbyResultCollectionCell" 
owner:self options:nil] lastObject];
 }
 
 - (void)didReceiveMemoryWarning
@@ -423,22 +432,22 @@
     // Dispose of any resources that can be recreated.
 }
 
-- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
+- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView 
*)collectionView
 {
     return 1;
 }
 
-- (NSInteger)tableView:(UITableView *)tableView 
numberOfRowsInSection:(NSInteger)section
+- (NSInteger)collectionView:(UICollectionView *)collectionView 
numberOfItemsInSection:(NSInteger)section
 {
     NSArray *sectionArray = self.nearbyDataArray[section];
     return sectionArray.count;
 }
 
--(void)updateLocationDataOfCell:(NearbyResultCell *)cell 
atIndexPath:(NSIndexPath *)indexPath
+-(void)updateLocationDataOfCell:(NearbyResultCollectionCell *)cell 
atIndexPath:(NSIndexPath *)indexPath
 {
     cell.headingAvailable = self.headingAvailable;
 
-    cell.deviceLocation = self.deviceLocation;
+    cell.deviceLocation = self.deviceLocation.coordinate;
 
     cell.interfaceOrientation = self.interfaceOrientation;
 
@@ -450,14 +459,15 @@
     NSDictionary *coords = rowData[@"coordinates"];
     NSNumber *latitude = coords[@"lat"];
     NSNumber *longitude = coords[@"lon"];
-    cell.location = [[CLLocation alloc] initWithLatitude: latitude.doubleValue
-                                               longitude: 
longitude.doubleValue];
+
+    cell.location =
+        CLLocationCoordinate2DMake(latitude.doubleValue, 
longitude.doubleValue);
 }
 
-- (UITableViewCell *)tableView:(UITableView *)tableView 
cellForRowAtIndexPath:(NSIndexPath *)indexPath
+- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView 
cellForItemAtIndexPath:(NSIndexPath *)indexPath
 {
     static NSString *cellID = TABLE_CELL_ID;
-    NearbyResultCell *cell = (NearbyResultCell *)[tableView 
dequeueReusableCellWithIdentifier:cellID];
+    NearbyResultCollectionCell *cell = (NearbyResultCollectionCell 
*)[collectionView dequeueReusableCellWithReuseIdentifier:cellID 
forIndexPath:indexPath];
 
     if (!cell.longPressRecognizer) {
         cell.longPressRecognizer = [[UILongPressGestureRecognizer alloc] 
initWithTarget:self action:@selector(longPressHappened:)];
@@ -500,7 +510,7 @@
     return self.nearbyDataArray[indexPath.section][indexPath.row];
 }
 
--(void)updateViewsInCell:(NearbyResultCell *)cell forIndexPath:(NSIndexPath 
*)indexPath
+-(void)updateViewsInCell:(NearbyResultCollectionCell *)cell 
forIndexPath:(NSIndexPath *)indexPath
 {
     NSDictionary *rowData = [self getRowDataForIndexPath:indexPath];
     
@@ -509,20 +519,23 @@
     [self updateLocationDataOfCell:cell atIndexPath:indexPath];
 }
 
-- (CGFloat)tableView:(UITableView *)tableView 
heightForRowAtIndexPath:(NSIndexPath *)indexPath
+- (CGSize)collectionView:(UICollectionView *)collectionView 
layout:(UICollectionViewLayout*)collectionViewLayout 
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
 {
     // Update the sizing cell with any data which could change the cell height.
     [self updateViewsInCell:self.offScreenSizingCell forIndexPath:indexPath];
 
+    CGFloat width = collectionView.bounds.size.width;
+
     // Determine height for the current configuration of the sizing cell.
-    return [tableView heightForSizingCell:self.offScreenSizingCell];
+    CGFloat height = [self.offScreenSizingCell 
heightForSizingCellOfWidth:width];
+    return CGSizeMake(width, height);
 }
 
 -(void)longPressHappened:(UILongPressGestureRecognizer *)gestureRecognizer
 {
     if (gestureRecognizer.state == UIGestureRecognizerStateBegan){
-        CGPoint p = [gestureRecognizer locationInView:self.tableView];
-        NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:p];
+        CGPoint p = [gestureRecognizer locationInView:self.collectionView];
+        NSIndexPath *indexPath = [self.collectionView 
indexPathForItemAtPoint:p];
         if (indexPath){
             self.longPressIndexPath = indexPath;
 

-- 
To view, visit https://gerrit.wikimedia.org/r/179978
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I8aa5a50aa21c26deba4b0de752a4e83668f749fa
Gerrit-PatchSet: 1
Gerrit-Project: apps/ios/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Mhurd <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to