Procházet zdrojové kódy

1.完成Apex Mobile首页数据展示和搜索。

Pen Li před 8 roky
rodič
revize
2192b6ac02

+ 35 - 3
Apex Mobile/Apex Mobile.xcodeproj/project.pbxproj

@@ -7,6 +7,9 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		42604122201C4B41002374A8 /* ShipingStatusCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 42604121201C4B41002374A8 /* ShipingStatusCell.m */; };
+		42604127201C578B002374A8 /* ShipSearchController.m in Sources */ = {isa = PBXBuildFile; fileRef = 42604126201C578B002374A8 /* ShipSearchController.m */; };
+		42604129201C57A7002374A8 /* ShipSearch.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 42604128201C57A7002374A8 /* ShipSearch.storyboard */; };
 		711BA6C1191E0525002EDE6F /* MessageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 711BA6C0191E0525002EDE6F /* MessageViewController.m */; };
 		711BA6C4191E0553002EDE6F /* MessageItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 711BA6C3191E0553002EDE6F /* MessageItem.m */; };
 		711DC6B218C30A4800FB1749 /* TableCellEdit.m in Sources */ = {isa = PBXBuildFile; fileRef = 711DC6B118C30A4800FB1749 /* TableCellEdit.m */; };
@@ -133,6 +136,11 @@
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXFileReference section */
+		42604120201C4B41002374A8 /* ShipingStatusCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShipingStatusCell.h; sourceTree = "<group>"; };
+		42604121201C4B41002374A8 /* ShipingStatusCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ShipingStatusCell.m; sourceTree = "<group>"; };
+		42604125201C578B002374A8 /* ShipSearchController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShipSearchController.h; sourceTree = "<group>"; };
+		42604126201C578B002374A8 /* ShipSearchController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ShipSearchController.m; sourceTree = "<group>"; };
+		42604128201C57A7002374A8 /* ShipSearch.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = ShipSearch.storyboard; sourceTree = "<group>"; };
 		711BA6BF191E0525002EDE6F /* MessageViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageViewController.h; sourceTree = "<group>"; };
 		711BA6C0191E0525002EDE6F /* MessageViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MessageViewController.m; sourceTree = "<group>"; };
 		711BA6C2191E0553002EDE6F /* MessageItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageItem.h; sourceTree = "<group>"; };
@@ -365,6 +373,28 @@
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
+		42604123201C53DB002374A8 /* Home */ = {
+			isa = PBXGroup;
+			children = (
+				715643BF2019B27500B04267 /* HomeViewController.h */,
+				715643C02019B27500B04267 /* HomeViewController.m */,
+				42604125201C578B002374A8 /* ShipSearchController.h */,
+				42604126201C578B002374A8 /* ShipSearchController.m */,
+				42604128201C57A7002374A8 /* ShipSearch.storyboard */,
+			);
+			name = Home;
+			sourceTree = "<group>";
+		};
+		42604124201C53ED002374A8 /* ShipStatusCell */ = {
+			isa = PBXGroup;
+			children = (
+				7162546C201C412E009E3A41 /* ShippingStatusCell.xib */,
+				42604120201C4B41002374A8 /* ShipingStatusCell.h */,
+				42604121201C4B41002374A8 /* ShipingStatusCell.m */,
+			);
+			name = ShipStatusCell;
+			sourceTree = "<group>";
+		};
 		71286AA918C7002F001FDF43 /* AES */ = {
 			isa = PBXGroup;
 			children = (
@@ -396,6 +426,8 @@
 		715643B820198A6000B04267 /* new */ = {
 			isa = PBXGroup;
 			children = (
+				42604124201C53ED002374A8 /* ShipStatusCell */,
+				42604123201C53DB002374A8 /* Home */,
 				7162546E201C51DC009E3A41 /* fake data */,
 				7162546A201C3AF1009E3A41 /* readme.txt */,
 				715643D8201C057E00B04267 /* ModeList */,
@@ -403,8 +435,6 @@
 				715643BA20198A9900B04267 /* RootViewController.m */,
 				715643BC2019AA9B00B04267 /* LoginViewController.h */,
 				715643BD2019AA9B00B04267 /* LoginViewController.m */,
-				715643BF2019B27500B04267 /* HomeViewController.h */,
-				715643C02019B27500B04267 /* HomeViewController.m */,
 				715643C22019B58400B04267 /* OrderHistoryViewController.h */,
 				715643C32019B58400B04267 /* OrderHistoryViewController.m */,
 				715643C52019BB6700B04267 /* StaticModelistViewController.h */,
@@ -419,7 +449,6 @@
 				715643CC2019BC6C00B04267 /* ToolslistViewController.m */,
 				715643CE2019BCCE00B04267 /* MylistViewController.h */,
 				715643CF2019BCCE00B04267 /* MylistViewController.m */,
-				7162546C201C412E009E3A41 /* ShippingStatusCell.xib */,
 			);
 			name = new;
 			sourceTree = "<group>";
@@ -851,6 +880,7 @@
 			files = (
 				71625470201C5205009E3A41 /* fake_container_list.json in Resources */,
 				7162546B201C3AF1009E3A41 /* readme.txt in Resources */,
+				42604129201C57A7002374A8 /* ShipSearch.storyboard in Resources */,
 				715643DC201C117300B04267 /* search.json in Resources */,
 				719EF8FF18BB839F00EFFF5F /* Images.xcassets in Resources */,
 				719EF8F418BB839F00EFFF5F /* Main_iPhone.storyboard in Resources */,
@@ -916,6 +946,7 @@
 				719A51A518C5A4AF0080C075 /* SimpleGrid.m in Sources */,
 				71286AB718C70061001FDF43 /* NSData+CommonCrypto.m in Sources */,
 				71A003FF18D6BFB40057CDFD /* ChangePasswordViewController.m in Sources */,
+				42604122201C4B41002374A8 /* ShipingStatusCell.m in Sources */,
 				71CEE38A18CB749E00052C63 /* DetailPageViewController.m in Sources */,
 				71286AB618C70061001FDF43 /* NSData+Base64.m in Sources */,
 				719E7E3318C0368A003408FF /* ApexMobileDB.m in Sources */,
@@ -950,6 +981,7 @@
 				713AA7A1191736E600B44092 /* DocumentsViewController.m in Sources */,
 				716FF7951904FBC600ED6C3D /* NewsTableViewCell.m in Sources */,
 				71A01D7918C9AE77003307A9 /* DetailCellKV.m in Sources */,
+				42604127201C578B002374A8 /* ShipSearchController.m in Sources */,
 				713AA7A41917373600B44092 /* LocalDocumentsViewController.m in Sources */,
 				71DA604A190A02CE00683003 /* FavoritesViewController.m in Sources */,
 				71BA50341908EDCF00D0BD31 /* HistoryTabBarController.m in Sources */,

+ 122 - 8
Apex Mobile/Apex Mobile/HomeViewController.m

@@ -7,8 +7,16 @@
 //
 
 #import "HomeViewController.h"
+#import "ShipingStatusCell.h"
+#import "ShipSearchController.h"
 
-@interface HomeViewController ()
+#define SHIP_CELL_IDENTIFIER @"ShippingStatusCell"
+
+@interface HomeViewController () <UITableViewDelegate,UITableViewDataSource,UISearchBarDelegate>
+
+@property (strong, nonatomic) IBOutlet UITableView *shipTableView;
+@property (strong, nonatomic) IBOutlet UISearchBar *shipSearchBar;
+@property (nonatomic,strong) NSMutableArray *shipArray;
 
 @end
 
@@ -17,6 +25,15 @@
 - (void)viewDidLoad {
     [super viewDidLoad];
     // Do any additional setup after loading the view.
+//    if (@available(iOS 11,*)) {
+//        self.shipTableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
+//    } else {
+//        self.automaticallyAdjustsScrollViewInsets = NO;
+//    }
+    
+    [self configureTableView];
+    self.shipSearchBar.delegate =self;
+    [self loadData];
 }
 
 - (void)didReceiveMemoryWarning {
@@ -24,14 +41,111 @@
     // Dispose of any resources that can be recreated.
 }
 
-/*
-#pragma mark - Navigation
+- (void)configureTableView {
+    
+    CGFloat w = CGRectGetWidth(self.shipTableView.bounds);
+    self.shipTableView.tableHeaderView =  [[UIView alloc] initWithFrame:CGRectMake(0, 0, w, CGFLOAT_MIN)];
+    self.shipTableView.tableFooterView = [UIView new];
+    
+    [self.shipTableView registerNib:[UINib nibWithNibName:@"ShippingStatusCell" bundle:nil] forCellReuseIdentifier:SHIP_CELL_IDENTIFIER];
+    
+    UIRefreshControl *refresh = [[UIRefreshControl alloc] init];
+    [refresh addTarget:self action:@selector(refreshControlValueChanged:) forControlEvents:UIControlEventValueChanged];
+    [self.shipTableView addSubview:refresh];
+}
+
+#pragma mark - Load Data
+
+- (NSMutableArray *)shipArray {
+    if (!_shipArray) {
+        _shipArray = [NSMutableArray array];
+    }
+    return _shipArray;
+}
+
+- (void)loadData {
+    NSString *path = [[NSBundle mainBundle] pathForResource:@"fake_container_list.json" ofType:nil];
+    NSData *data = [[NSData alloc] initWithContentsOfFile:path];
+    
+    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
+    [self.shipArray removeAllObjects];
+    [self.shipArray addObjectsFromArray:[json objectForKey:@"container_list"]];
+    
+    [self.shipTableView reloadData];
+}
+
+#pragma mark - Actino
+
+- (void)refreshControlValueChanged:(UIRefreshControl *)refresh {
+    [self loadData];
+    [refresh endRefreshing];
+}
+
+#pragma mark - TableView DataSource && Delegate
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+    return self.shipArray.count;
+}
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    return 1;
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    
+    ShipingStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:SHIP_CELL_IDENTIFIER forIndexPath:indexPath];
+    
+    NSDictionary *item = [self.shipArray objectAtIndex:indexPath.section];
+    
+    NSString *status = [item objectForKey:@"315_status"];
+    NSString *icon = [item objectForKey:@"icon"];
+    NSString *desc = [item objectForKey:@"description"];
+    NSString *detail = [item objectForKey:@"detail"];
+    NSString *time = [item objectForKey:@"date_time"];
+    NSString *location = [item objectForKey:@"last_location"];
+    
+    [[[[[[cell setStatus:status] setDescription:desc] setDetail:detail] setLastLocation:location] setTime:time] setIcon:icon];
+    
+    return cell;
+}
+
+//- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
+//    CGFloat w = CGRectGetWidth(tableView.bounds);
+//
+//    UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0, 0, w, 30)];
+//    header.backgroundColor = [UIColor lightGrayColor];
+//
+//    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 5, w - 10 * 2, 20)];
+//    label.textColor = [UIColor whiteColor];
+//    label.text = @"Recently";
+//
+//    [header addSubview:label];
+//    return header;
+//}
+
+- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
+    return 0.1;
+}
+
+- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
+    return 10;
+}
+
+- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
+    return 110;
+}
+
+#pragma mark - SearchBar Delegate
 
-// In a storyboard-based application, you will often want to do a little preparation before navigation
-- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
-    // Get the new view controller using [segue destinationViewController].
-    // Pass the selected object to the new view controller.
+- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
+    
+    ShipSearchController *searchVC = [ShipSearchController build];
+    
+    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:searchVC];
+    
+    [self presentViewController:nav animated:YES completion:nil];
+    
+    return NO;
 }
-*/
 
 @end

+ 49 - 10
Apex Mobile/Apex Mobile/Main.storyboard

@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="YOs-rL-bRV">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="YOs-rL-bRV">
     <device id="retina4_7" orientation="portrait">
         <adaptation id="fullscreen"/>
     </device>
     <dependencies>
         <deployment version="2304" identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13527"/>
         <capability name="Safe area layout guides" minToolsVersion="9.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
@@ -192,9 +192,11 @@
                         <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
-                            <toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6HR-cD-QDf">
+                            <toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="6HR-cD-QDf">
                                 <rect key="frame" x="0.0" y="20" width="375" height="44"/>
-                                <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="44" id="nHL-De-PVp"/>
+                                </constraints>
                                 <items>
                                     <barButtonItem style="plain" id="YgG-oK-nME">
                                         <searchBar key="customView" contentMode="redraw" placeholder="Search Container" id="VZb-rJ-cHv">
@@ -205,17 +207,54 @@
                                     </barButtonItem>
                                 </items>
                             </toolbar>
-                            <tableView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" translatesAutoresizingMaskIntoConstraints="NO" id="iIl-j9-7oa">
-                                <rect key="frame" x="0.0" y="64" width="375" height="554"/>
-                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                            <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" translatesAutoresizingMaskIntoConstraints="NO" id="iIl-j9-7oa">
+                                <rect key="frame" x="0.0" y="94" width="375" height="524"/>
                                 <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
+                                <inset key="separatorInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
+                                <connections>
+                                    <outlet property="dataSource" destination="ucJ-C2-JJ8" id="87k-f6-Pjn"/>
+                                    <outlet property="delegate" destination="ucJ-C2-JJ8" id="qcO-e8-lls"/>
+                                </connections>
                             </tableView>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3xo-DP-qWN">
+                                <rect key="frame" x="0.0" y="64" width="375" height="30"/>
+                                <subviews>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Recently" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ouQ-Yg-iZI">
+                                        <rect key="frame" x="10" y="5" width="66.5" height="21"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                        <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                </subviews>
+                                <color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
+                                <constraints>
+                                    <constraint firstItem="ouQ-Yg-iZI" firstAttribute="centerY" secondItem="3xo-DP-qWN" secondAttribute="centerY" id="LEb-qr-SVl"/>
+                                    <constraint firstItem="ouQ-Yg-iZI" firstAttribute="leading" secondItem="3xo-DP-qWN" secondAttribute="leading" constant="10" id="PPM-oF-8FH"/>
+                                    <constraint firstAttribute="height" constant="30" id="bFZ-hk-yg5"/>
+                                </constraints>
+                            </view>
                         </subviews>
                         <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                        <constraints>
+                            <constraint firstItem="3xo-DP-qWN" firstAttribute="top" secondItem="6HR-cD-QDf" secondAttribute="bottom" id="6GN-qy-A4V"/>
+                            <constraint firstItem="iIl-j9-7oa" firstAttribute="trailing" secondItem="HNS-Qr-K3s" secondAttribute="trailing" id="9jR-8W-zYM"/>
+                            <constraint firstItem="HNS-Qr-K3s" firstAttribute="trailing" secondItem="3xo-DP-qWN" secondAttribute="trailing" id="Gvc-tU-QdZ"/>
+                            <constraint firstItem="iIl-j9-7oa" firstAttribute="top" secondItem="3xo-DP-qWN" secondAttribute="bottom" id="JZI-44-qDk"/>
+                            <constraint firstItem="6HR-cD-QDf" firstAttribute="top" secondItem="HNS-Qr-K3s" secondAttribute="top" id="PPI-EY-buy"/>
+                            <constraint firstItem="6HR-cD-QDf" firstAttribute="trailing" secondItem="HNS-Qr-K3s" secondAttribute="trailing" id="XrC-UT-lWj"/>
+                            <constraint firstItem="6HR-cD-QDf" firstAttribute="leading" secondItem="HNS-Qr-K3s" secondAttribute="leading" id="eiY-l1-JU6"/>
+                            <constraint firstItem="iIl-j9-7oa" firstAttribute="leading" secondItem="HNS-Qr-K3s" secondAttribute="leading" id="lPc-7m-bBJ"/>
+                            <constraint firstItem="3xo-DP-qWN" firstAttribute="leading" secondItem="HNS-Qr-K3s" secondAttribute="leading" id="mui-fH-ZHN"/>
+                            <constraint firstItem="iIl-j9-7oa" firstAttribute="bottom" secondItem="HNS-Qr-K3s" secondAttribute="bottom" id="nZz-HM-ESm"/>
+                        </constraints>
                         <viewLayoutGuide key="safeArea" id="HNS-Qr-K3s"/>
                     </view>
                     <tabBarItem key="tabBarItem" title="Home" image="tab_home" id="OC9-MV-8nf"/>
                     <simulatedTabBarMetrics key="simulatedBottomBarMetrics"/>
+                    <connections>
+                        <outlet property="shipSearchBar" destination="VZb-rJ-cHv" id="cXc-Mo-ooR"/>
+                        <outlet property="shipTableView" destination="iIl-j9-7oa" id="vsk-WU-ScI"/>
+                    </connections>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="Smq-yU-AsP" userLabel="First Responder" sceneMemberID="firstResponder"/>
             </objects>
@@ -290,9 +329,9 @@
     </scenes>
     <resources>
         <image name="apexlogo-2" width="129" height="32"/>
-        <image name="tab_history" width="66" height="66"/>
-        <image name="tab_home" width="66" height="66"/>
-        <image name="tab_login" width="66" height="66"/>
+        <image name="tab_history" width="30" height="30"/>
+        <image name="tab_home" width="30" height="30"/>
+        <image name="tab_login" width="30" height="30"/>
         <image name="tools" width="32" height="32"/>
         <image name="unchecked_32" width="16" height="16"/>
     </resources>

+ 66 - 0
Apex Mobile/Apex Mobile/ShipSearch.storyboard

@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina4_7" orientation="portrait">
+        <adaptation id="fullscreen"/>
+    </device>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13527"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <scenes>
+        <!--Ship Search Controller-->
+        <scene sceneID="vXF-J2-qgu">
+            <objects>
+                <viewController storyboardIdentifier="ShipSearchController" useStoryboardIdentifierAsRestorationIdentifier="YES" id="hfn-xJ-pdm" customClass="ShipSearchController" sceneMemberID="viewController">
+                    <view key="view" contentMode="scaleToFill" id="7Ur-fK-9cR">
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <searchBar contentMode="redraw" searchBarStyle="prominent" text="" placeholder="Search" showsCancelButton="YES" translatesAutoresizingMaskIntoConstraints="NO" id="brK-bP-B3P">
+                                <rect key="frame" x="0.0" y="20" width="375" height="56"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="56" id="3Sz-nz-CE0"/>
+                                </constraints>
+                                <textInputTraits key="textInputTraits" returnKeyType="search"/>
+                                <scopeButtonTitles>
+                                    <string>Title</string>
+                                    <string>Title</string>
+                                </scopeButtonTitles>
+                                <connections>
+                                    <outlet property="delegate" destination="hfn-xJ-pdm" id="xBR-8k-ofQ"/>
+                                </connections>
+                            </searchBar>
+                            <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" translatesAutoresizingMaskIntoConstraints="NO" id="1MM-Qg-f3V">
+                                <rect key="frame" x="0.0" y="76" width="375" height="591"/>
+                                <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
+                                <connections>
+                                    <outlet property="dataSource" destination="hfn-xJ-pdm" id="G1r-RX-tht"/>
+                                    <outlet property="delegate" destination="hfn-xJ-pdm" id="HfR-Bn-iwn"/>
+                                </connections>
+                            </tableView>
+                        </subviews>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                        <constraints>
+                            <constraint firstItem="1MM-Qg-f3V" firstAttribute="leading" secondItem="FT7-lQ-k3y" secondAttribute="leading" id="8ks-s2-gFp"/>
+                            <constraint firstItem="brK-bP-B3P" firstAttribute="leading" secondItem="FT7-lQ-k3y" secondAttribute="leading" id="FX9-m2-AtS"/>
+                            <constraint firstItem="1MM-Qg-f3V" firstAttribute="top" secondItem="brK-bP-B3P" secondAttribute="bottom" id="M9X-Kq-qNQ"/>
+                            <constraint firstItem="FT7-lQ-k3y" firstAttribute="trailing" secondItem="1MM-Qg-f3V" secondAttribute="trailing" id="boI-D3-yuu"/>
+                            <constraint firstItem="brK-bP-B3P" firstAttribute="trailing" secondItem="FT7-lQ-k3y" secondAttribute="trailing" id="dpb-nC-P2h"/>
+                            <constraint firstItem="FT7-lQ-k3y" firstAttribute="bottom" secondItem="1MM-Qg-f3V" secondAttribute="bottom" id="nhX-XE-chI"/>
+                            <constraint firstItem="brK-bP-B3P" firstAttribute="top" secondItem="FT7-lQ-k3y" secondAttribute="top" id="zSZ-lR-jSt"/>
+                        </constraints>
+                        <viewLayoutGuide key="safeArea" id="FT7-lQ-k3y"/>
+                    </view>
+                    <connections>
+                        <outlet property="searchBar" destination="brK-bP-B3P" id="av0-76-gnh"/>
+                        <outlet property="searchTable" destination="1MM-Qg-f3V" id="zZa-CR-inz"/>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="4Ek-ep-yhV" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="-241" y="6"/>
+        </scene>
+    </scenes>
+</document>

+ 15 - 0
Apex Mobile/Apex Mobile/ShipSearchController.h

@@ -0,0 +1,15 @@
+//
+//  ShipSearchController.h
+//  Apex Mobile
+//
+//  Created by Jack on 2018/1/27.
+//  Copyright © 2018年 United Software Applications, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface ShipSearchController : UIViewController
+
++ (instancetype)build;
+
+@end

+ 171 - 0
Apex Mobile/Apex Mobile/ShipSearchController.m

@@ -0,0 +1,171 @@
+//
+//  ShipSearchController.m
+//  Apex Mobile
+//
+//  Created by Jack on 2018/1/27.
+//  Copyright © 2018年 United Software Applications, Inc. All rights reserved.
+//
+
+#import "ShipSearchController.h"
+#import "ShipingStatusCell.h"
+
+#define SEARCH_CELL_IDENTIFIER @"SearchShippingStatusCell"
+
+@interface ShipSearchController () <UISearchBarDelegate,UITableViewDelegate,UITableViewDataSource>
+@property (strong, nonatomic) IBOutlet UISearchBar *searchBar;
+@property (strong, nonatomic) IBOutlet UITableView *searchTable;
+@property (nonatomic,strong) UISegmentedControl *segmentedControl;
+@property (nonatomic,assign) NSUInteger currentMode;
+@property (nonatomic,strong) NSMutableArray *shipArray;
+
+@end
+
+@implementation ShipSearchController
+
++ (instancetype)build {
+    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"ShipSearch" bundle:nil];
+    ShipSearchController *vc = [storyboard instantiateViewControllerWithIdentifier:@"ShipSearchController"];
+    return vc;
+}
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    
+    [self configureNavigationBar];
+    [self configureTableView];
+}
+
+- (void)didReceiveMemoryWarning {
+    [super didReceiveMemoryWarning];
+    // Dispose of any resources that can be recreated.
+}
+
+#pragma mark - Load Data
+
+- (NSMutableArray *)shipArray {
+    if (!_shipArray) {
+        _shipArray = [NSMutableArray array];
+    }
+    return _shipArray;
+}
+
+- (void)loadData {
+    NSString *path = [[NSBundle mainBundle] pathForResource:@"fake_container_list.json" ofType:nil];
+    NSData *data = [[NSData alloc] initWithContentsOfFile:path];
+    
+    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
+    [self.shipArray removeAllObjects];
+    [self.shipArray addObjectsFromArray:[json objectForKey:@"container_list"]];
+    
+    [self.searchTable reloadData];
+}
+
+#pragma mark - Private
+
+- (UISegmentedControl *)segmentedControl {
+    if (!_segmentedControl) {
+        _segmentedControl = [[UISegmentedControl alloc] initWithItems:@[@"H BOL",@"Container#"]];
+        [_segmentedControl addTarget:self action:@selector(segmentedControlClick:) forControlEvents:UIControlEventValueChanged];
+    }
+    return _segmentedControl;
+}
+
+- (void)configureNavigationBar {
+    
+    UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle:@"back" style:UIBarButtonItemStylePlain target:self action:@selector(backBtnClick:)];
+    self.navigationItem.leftBarButtonItem = backItem;
+    
+    self.currentMode = 0;
+    self.segmentedControl.selectedSegmentIndex = self.currentMode;
+    self.navigationItem.titleView = self.segmentedControl;
+}
+
+- (void)configureTableView {
+    CGFloat w = CGRectGetWidth(self.searchTable.bounds);
+    self.searchTable.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, w, CGFLOAT_MIN)];
+    self.searchTable.tableFooterView = [UIView new];
+    
+    [self.searchTable registerNib:[UINib nibWithNibName:@"ShippingStatusCell" bundle:nil] forCellReuseIdentifier:SEARCH_CELL_IDENTIFIER];
+}
+
+#pragma mark - Action
+
+- (void)backBtnClick:(id)sender {
+    [self dismissViewControllerAnimated:YES completion:nil];
+}
+
+- (void)segmentedControlClick:(id)sender {
+    self.currentMode = self.segmentedControl.selectedSegmentIndex;
+}
+
+#pragma mark - TableView DataSource && Delegate
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+    return self.shipArray.count;
+}
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    return 1;
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    
+    ShipingStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:SEARCH_CELL_IDENTIFIER forIndexPath:indexPath];
+    
+    NSDictionary *item = [self.shipArray objectAtIndex:indexPath.row];
+    
+    NSString *status = [item objectForKey:@"315_status"];
+    NSString *icon = [item objectForKey:@"icon"];
+    NSString *desc = [item objectForKey:@"description"];
+    NSString *detail = [item objectForKey:@"detail"];
+    NSString *time = [item objectForKey:@"date_time"];
+    NSString *location = [item objectForKey:@"last_location"];
+    
+    [[[[[[cell setStatus:status] setDescription:desc] setDetail:detail] setLastLocation:location] setTime:time] setIcon:icon];
+    
+    return cell;
+}
+
+//- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
+//    CGFloat w = CGRectGetWidth(tableView.bounds);
+//
+//    UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0, 0, w, 30)];
+//    header.backgroundColor = [UIColor lightGrayColor];
+//
+//    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 5, w - 10 * 2, 20)];
+//    label.textColor = [UIColor whiteColor];
+//    label.text = @"Recently";
+//
+//    [header addSubview:label];
+//    return header;
+//}
+
+- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
+    return 0.1;
+}
+
+- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
+    return 10;
+}
+
+- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
+    return 110;
+}
+
+#pragma mark - SearchBar Delegate
+
+- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
+    
+    return YES;
+}
+
+- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
+    [self loadData];
+}
+
+- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
+    [searchBar resignFirstResponder];
+}
+
+@end

+ 20 - 0
Apex Mobile/Apex Mobile/ShipingStatusCell.h

@@ -0,0 +1,20 @@
+//
+//  ShipingStatusCell.h
+//  Apex Mobile
+//
+//  Created by Jack on 2018/1/27.
+//  Copyright © 2018年 United Software Applications, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface ShipingStatusCell : UITableViewCell
+
+- (instancetype)setStatus:(NSString *)status;
+- (instancetype)setLastLocation:(NSString *)lastLocation;
+- (instancetype)setTime:(NSString *)time;
+- (instancetype)setDescription:(NSString *)desc;
+- (instancetype)setDetail:(NSString *)detail;
+- (instancetype)setIcon:(NSString *)icon;
+
+@end

+ 111 - 0
Apex Mobile/Apex Mobile/ShipingStatusCell.m

@@ -0,0 +1,111 @@
+//
+//  ShipingStatusCell.m
+//  Apex Mobile
+//
+//  Created by Jack on 2018/1/27.
+//  Copyright © 2018年 United Software Applications, Inc. All rights reserved.
+//
+
+#import "ShipingStatusCell.h"
+
+
+@interface ShipingStatusCell ()
+
+@property (strong, nonatomic) IBOutlet UILabel *statusLabel;
+@property (strong, nonatomic) IBOutlet UILabel *lastLocationLabel;
+@property (strong, nonatomic) IBOutlet UILabel *timeLabel;
+@property (strong, nonatomic) IBOutlet UIImageView *iconView;
+@property (strong, nonatomic) IBOutlet UILabel *descLabel;
+@property (strong, nonatomic) IBOutlet UILabel *detailLabel;
+
+@property (nonatomic,strong) NSOperation *operation;
+@property (nonatomic,strong) NSOperationQueue *queue;
+
+@end
+
+@implementation ShipingStatusCell
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    // Initialization code
+}
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
+    [super setSelected:selected animated:animated];
+
+    // Configure the view for the selected state
+}
+
+- (NSOperationQueue *)queue {
+    if (!_queue) {
+        _queue = [[NSOperationQueue alloc] init];
+    }
+    return _queue;
+}
+
+- (instancetype)setStatus:(NSString *)status {
+    self.statusLabel.text = status;
+    return self;
+}
+
+- (instancetype)setLastLocation:(NSString *)lastLocation {
+    self.lastLocationLabel.text = lastLocation;
+    return self;
+}
+
+- (instancetype)setTime:(NSString *)time {
+    self.timeLabel.text = time;
+    return self;
+}
+
+- (instancetype)setDescription:(NSString *)desc {
+    self.descLabel.text = desc;
+    return self;
+}
+
+- (instancetype)setDetail:(NSString *)detail {
+    self.detailLabel.text = detail;
+    return self;
+}
+
+- (instancetype)setIcon:(NSString *)icon {
+
+//    if (self.operation && self.operation.isExecuting) {
+//        [self.operation cancel];
+//    }
+//
+//    if (icon) {
+//        __weak typeof(self) weakSelf = self;
+//        self.operation = [NSBlockOperation blockOperationWithBlock:^{
+//
+//            NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:icon]];
+//            UIImage *icon = [UIImage imageWithData:imgData];
+//            dispatch_async(dispatch_get_main_queue(), ^{
+//                weakSelf.iconView.image = icon;
+//            });
+//
+//        }];
+//
+//        [self.queue addOperation:self.operation];
+//
+//    } else {
+//        self.operation = nil;
+//        self.iconView.image = nil;
+//    }
+
+    if (icon) {
+        self.iconView.image = [UIImage imageNamed:icon];
+    } else {
+        self.iconView.image = nil;
+    }
+    
+    return self;
+}
+
+- (void)prepareForReuse {
+    [super prepareForReuse];
+    
+    [[[[[[self setStatus:nil] setLastLocation:nil] setTime:nil] setDescription:nil] setDetail:nil] setIcon:nil];
+}
+
+@end

+ 70 - 26
Apex Mobile/Apex Mobile/ShippingStatusCell.xib

@@ -1,69 +1,113 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
     <device id="retina4_7" orientation="portrait">
         <adaptation id="fullscreen"/>
     </device>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13527"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
         <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-        <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" rowHeight="108" id="tck-7a-pd9">
-            <rect key="frame" x="0.0" y="0.0" width="375" height="96"/>
+        <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" rowHeight="110" id="tck-7a-pd9" customClass="ShipingStatusCell">
+            <rect key="frame" x="0.0" y="0.0" width="375" height="110"/>
             <autoresizingMask key="autoresizingMask"/>
             <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="tck-7a-pd9" id="9kY-ry-WFt">
-                <rect key="frame" x="0.0" y="0.0" width="375" height="95.5"/>
+                <rect key="frame" x="0.0" y="0.0" width="375" height="109.5"/>
                 <autoresizingMask key="autoresizingMask"/>
                 <subviews>
-                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="315 Status" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="NSI-Dy-9wQ">
-                        <rect key="frame" x="15" y="10" width="90" height="21"/>
-                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="315 Status" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="NSI-Dy-9wQ">
+                        <rect key="frame" x="15" y="10" width="73" height="21"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="21" id="dih-96-Cy7"/>
+                        </constraints>
                         <fontDescription key="fontDescription" type="system" pointSize="15"/>
                         <nil key="textColor"/>
                         <nil key="highlightedColor"/>
                     </label>
-                    <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zzT-Tl-h4X">
-                        <rect key="frame" x="15" y="37" width="48" height="48"/>
-                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                    <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="zzT-Tl-h4X">
+                        <rect key="frame" x="15" y="57" width="48" height="48"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="48" id="QkP-uV-fWa"/>
+                            <constraint firstAttribute="width" constant="48" id="nFE-z2-5cD"/>
+                        </constraints>
                     </imageView>
-                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="latest update information shows here include location, status, time, etc" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GXE-Kf-rIH">
-                        <rect key="frame" x="71" y="55" width="288" height="15"/>
-                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="latest update information shows here include location, status, time, etc" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GXE-Kf-rIH">
+                        <rect key="frame" x="71" y="80" width="289" height="14.5"/>
                         <fontDescription key="fontDescription" type="system" pointSize="12"/>
                         <color key="textColor" red="0.36078431370000003" green="0.38823529410000002" blue="0.4039215686" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                         <nil key="highlightedColor"/>
                     </label>
-                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Last Location" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="X99-0j-XQm">
-                        <rect key="frame" x="173" y="10" width="186" height="21"/>
-                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Last Location" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="X99-0j-XQm">
+                        <rect key="frame" x="15" y="31" width="92" height="21"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="21" id="ckh-V6-4Az"/>
+                        </constraints>
                         <fontDescription key="fontDescription" type="system" pointSize="15"/>
                         <nil key="textColor"/>
                         <nil key="highlightedColor"/>
                     </label>
-                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="HBOL &amp;  container #" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Y76-2K-QNR">
-                        <rect key="frame" x="71" y="37" width="288" height="18"/>
-                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="HBOL &amp;  container #" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Y76-2K-QNR">
+                        <rect key="frame" x="71" y="57" width="289" height="18"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="18" id="AVN-RC-itM"/>
+                        </constraints>
                         <fontDescription key="fontDescription" type="system" pointSize="15"/>
                         <nil key="textColor"/>
                         <nil key="highlightedColor"/>
                     </label>
-                    <view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="n0i-nd-KME">
-                        <rect key="frame" x="370" y="0.0" width="5" height="96"/>
-                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="n0i-nd-KME">
+                        <rect key="frame" x="370" y="0.0" width="5" height="110"/>
                         <color key="backgroundColor" red="0.0" green="0.56031829119999998" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                        <constraints>
+                            <constraint firstAttribute="width" constant="5" id="DWZ-1n-IWP"/>
+                        </constraints>
                     </view>
-                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="01/10/2018 02:21" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="A9v-MV-LqP">
-                        <rect key="frame" x="71" y="70" width="288" height="15"/>
-                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="01/10/2018 02:21" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="A9v-MV-LqP">
+                        <rect key="frame" x="260" y="37" width="105" height="15"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="15" id="u17-bd-sqI"/>
+                            <constraint firstAttribute="width" constant="105" id="zXD-P7-Zke"/>
+                        </constraints>
                         <fontDescription key="fontDescription" type="system" pointSize="12"/>
                         <color key="textColor" red="0.36078431370000003" green="0.38823529410000002" blue="0.4039215686" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                         <nil key="highlightedColor"/>
                     </label>
                 </subviews>
+                <constraints>
+                    <constraint firstItem="X99-0j-XQm" firstAttribute="top" secondItem="NSI-Dy-9wQ" secondAttribute="bottom" id="0RS-vv-Tyi"/>
+                    <constraint firstItem="NSI-Dy-9wQ" firstAttribute="top" secondItem="9kY-ry-WFt" secondAttribute="top" constant="10" id="0x2-9N-9Gx"/>
+                    <constraint firstItem="X99-0j-XQm" firstAttribute="leading" secondItem="9kY-ry-WFt" secondAttribute="leading" constant="15" id="44L-zb-gLg"/>
+                    <constraint firstItem="zzT-Tl-h4X" firstAttribute="top" secondItem="X99-0j-XQm" secondAttribute="bottom" constant="5" id="83c-xi-Sfi"/>
+                    <constraint firstItem="zzT-Tl-h4X" firstAttribute="leading" secondItem="9kY-ry-WFt" secondAttribute="leading" constant="15" id="8YL-SL-YfK"/>
+                    <constraint firstAttribute="trailing" secondItem="n0i-nd-KME" secondAttribute="trailing" id="DxD-fy-Wmq"/>
+                    <constraint firstItem="n0i-nd-KME" firstAttribute="leading" secondItem="GXE-Kf-rIH" secondAttribute="trailing" constant="10" id="OjN-xO-iJz"/>
+                    <constraint firstItem="Y76-2K-QNR" firstAttribute="leading" secondItem="zzT-Tl-h4X" secondAttribute="trailing" constant="8" id="PYE-p2-t6z"/>
+                    <constraint firstItem="GXE-Kf-rIH" firstAttribute="top" secondItem="Y76-2K-QNR" secondAttribute="bottom" constant="5" id="PyT-en-aqn"/>
+                    <constraint firstItem="NSI-Dy-9wQ" firstAttribute="leading" secondItem="9kY-ry-WFt" secondAttribute="leading" constant="15" id="QNP-sF-OD5"/>
+                    <constraint firstItem="n0i-nd-KME" firstAttribute="top" secondItem="9kY-ry-WFt" secondAttribute="top" id="RtR-AN-v5X"/>
+                    <constraint firstItem="GXE-Kf-rIH" firstAttribute="leading" secondItem="zzT-Tl-h4X" secondAttribute="trailing" constant="8" id="bLG-O5-Z3P"/>
+                    <constraint firstItem="Y76-2K-QNR" firstAttribute="top" secondItem="X99-0j-XQm" secondAttribute="bottom" constant="5" id="fs1-bX-ehj"/>
+                    <constraint firstItem="n0i-nd-KME" firstAttribute="leading" secondItem="Y76-2K-QNR" secondAttribute="trailing" constant="10" id="iV1-5N-bTi"/>
+                    <constraint firstItem="A9v-MV-LqP" firstAttribute="bottom" secondItem="X99-0j-XQm" secondAttribute="bottom" id="qew-Vg-TuB"/>
+                    <constraint firstItem="n0i-nd-KME" firstAttribute="leading" secondItem="A9v-MV-LqP" secondAttribute="trailing" constant="5" id="tXz-FP-Fzd"/>
+                    <constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="GXE-Kf-rIH" secondAttribute="bottom" id="tYK-6n-E8u"/>
+                    <constraint firstItem="A9v-MV-LqP" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="X99-0j-XQm" secondAttribute="trailing" constant="5" id="xby-XX-fU2"/>
+                </constraints>
             </tableViewCellContentView>
+            <constraints>
+                <constraint firstItem="n0i-nd-KME" firstAttribute="height" secondItem="tck-7a-pd9" secondAttribute="height" id="vJd-6b-AGT"/>
+            </constraints>
+            <connections>
+                <outlet property="descLabel" destination="Y76-2K-QNR" id="nvv-dh-hdz"/>
+                <outlet property="detailLabel" destination="GXE-Kf-rIH" id="ils-ci-0eO"/>
+                <outlet property="iconView" destination="zzT-Tl-h4X" id="CiS-Ec-KJw"/>
+                <outlet property="lastLocationLabel" destination="X99-0j-XQm" id="PJ5-0E-YuA"/>
+                <outlet property="statusLabel" destination="NSI-Dy-9wQ" id="TmI-dP-4GZ"/>
+                <outlet property="timeLabel" destination="A9v-MV-LqP" id="7Br-4s-QfR"/>
+            </connections>
             <point key="canvasLocation" x="195.5" y="-336"/>
         </tableViewCell>
     </objects>

+ 35 - 3
Apex Mobile/Apex Mobile/fake_container_list.json

@@ -10,11 +10,11 @@
                        },
                        {
                        "315_status": "Container loaded on vessel",
-                       "icon": "status_load",
+                       "icon": "status_load_vessel",
                        "description": "A1801350973 - GESU1059076",
                        "detail": "Container# GESU1059076 loaded on vessel YM UBIQUITY",
                        "date_time": "01/21/2018 00:15",
-                       "last_location": "QINGDAO, CHINA (CNTAO)"
+                       "last_location": "QINGDAO, (CNTAO)"
                        },
                        {
                        "315_status": "Pickup/Delivery",
@@ -22,7 +22,39 @@
                        "description": "148517008980 - UACU3259986",
                        "detail": "Container# UACU3259986 available for pickup or delivery",
                        "date_time": "01/23/2018 15:18",
-                       "last_location": "WORCESTER, MA (USORH)"
+                       "last_location": "WORCESTER, (USORH)"
+                       },
+                       {
+                       "315_status": "Pickup/Delivery",
+                       "icon": "status_delivery",
+                       "description": "148517008980 - UACU3259986",
+                       "detail": "Container# UACU3259986 available for pickup or delivery",
+                       "date_time": "01/23/2018 15:18",
+                       "last_location": "WORCESTER, (USORH)"
+                       },
+                       {
+                       "315_status": "Pickup/Delivery",
+                       "icon": "status_delivery",
+                       "description": "148517008980 - UACU3259986",
+                       "detail": "Container# UACU3259986 available for pickup or delivery",
+                       "date_time": "01/23/2018 15:18",
+                       "last_location": "WORCESTER, (USORH)"
+                       },
+                       {
+                       "315_status": "Pickup/Delivery",
+                       "icon": "status_delivery",
+                       "description": "148517008980 - UACU3259986",
+                       "detail": "Container# UACU3259986 available for pickup or delivery",
+                       "date_time": "01/23/2018 15:18",
+                       "last_location": "WORCESTER, (USORH)"
+                       },
+                       {
+                       "315_status": "Pickup/Delivery",
+                       "icon": "status_delivery",
+                       "description": "148517008980 - UACU3259986",
+                       "detail": "Container# UACU3259986 available for pickup or delivery",
+                       "date_time": "01/23/2018 15:18",
+                       "last_location": "WORCESTER, (USORH)"
                        }
                        ],
     "result": -1