Przeglądaj źródła

1.修改iOS Apex Mobile Location标签点击事件处理不正确。
2.修改iOS Apex Mobile Recent点击更新地图。

Pen Li 8 lat temu
rodzic
commit
c4b4850101

+ 6 - 0
Apex Mobile/Apex Mobile.xcodeproj/project.pbxproj

@@ -8,6 +8,7 @@
 
 /* Begin PBXBuildFile section */
 		420F0CA420901C2E005C4690 /* KPIRepeatTapGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 420F0CA320901C2E005C4690 /* KPIRepeatTapGestureRecognizer.m */; };
+		42253C94209C007700879B09 /* AMMapView.m in Sources */ = {isa = PBXBuildFile; fileRef = 42253C93209C007700879B09 /* AMMapView.m */; };
 		4235C30320229F7200A99D04 /* Result.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4235C30220229F7200A99D04 /* Result.xib */; };
 		4235C3052022A60A00A99D04 /* ResultCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4235C3042022A60A00A99D04 /* ResultCell.xib */; };
 		4253900E2079B7C700ECF982 /* KPIPieChartCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4253900C2079B7C700ECF982 /* KPIPieChartCell.m */; };
@@ -193,6 +194,8 @@
 /* Begin PBXFileReference section */
 		420F0CA220901C2E005C4690 /* KPIRepeatTapGestureRecognizer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KPIRepeatTapGestureRecognizer.h; sourceTree = "<group>"; };
 		420F0CA320901C2E005C4690 /* KPIRepeatTapGestureRecognizer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KPIRepeatTapGestureRecognizer.m; sourceTree = "<group>"; };
+		42253C92209C007700879B09 /* AMMapView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AMMapView.h; sourceTree = "<group>"; };
+		42253C93209C007700879B09 /* AMMapView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AMMapView.m; sourceTree = "<group>"; };
 		4235C30220229F7200A99D04 /* Result.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Result.xib; path = ../../common/customUI/Result.xib; sourceTree = "<group>"; };
 		4235C3042022A60A00A99D04 /* ResultCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ResultCell.xib; path = ../../common/customUI/ResultCell.xib; sourceTree = "<group>"; };
 		4253900B2079B7C700ECF982 /* KPIPieChartCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KPIPieChartCell.h; sourceTree = "<group>"; };
@@ -882,6 +885,8 @@
 				42BCACC9209AE243009DDA43 /* AMAnnotationView.m */,
 				42BCACCB209AE342009DDA43 /* AMMapAnnotaion.h */,
 				42BCACCC209AE342009DDA43 /* AMMapAnnotaion.m */,
+				42253C92209C007700879B09 /* AMMapView.h */,
+				42253C93209C007700879B09 /* AMMapView.m */,
 			);
 			name = Location;
 			sourceTree = "<group>";
@@ -1351,6 +1356,7 @@
 				715709AE20215CB000EFE5C5 /* RANetwork.m in Sources */,
 				425390222079B99B00ECF982 /* XYRotatedView.m in Sources */,
 				719EF8FD18BB839F00EFFF5F /* ApexMobileSecondViewController.m in Sources */,
+				42253C94209C007700879B09 /* AMMapView.m in Sources */,
 				715709BA20215E0000EFE5C5 /* NSString+Base64.m in Sources */,
 				71AE427318C47AF900B8EC3D /* SearchViewController.m in Sources */,
 				715643BE2019AA9B00B04267 /* LoginViewController.m in Sources */,

+ 2 - 0
Apex Mobile/Apex Mobile/AMAnnotationView.h

@@ -14,6 +14,8 @@
 
 - (void)mapView:(MKMapView *)mapView didTapAnnotaionCallout:(AMMapAnnotaion *)annotation;
 
+//- (BOOL)mapView:(MKMapView *)mapView canSelectAnnotaion:(AMMapAnnotaion *)annotation;
+
 @end
 
 @interface AMAnnotationView : MKAnnotationView

+ 38 - 24
Apex Mobile/Apex Mobile/AMAnnotationView.m

@@ -11,7 +11,7 @@
 
 @interface AMAnnotationView ()
 
-@property (strong,nonatomic) UIView *calloutView;
+@property (strong,nonatomic) UIControl *calloutView;
 @property (strong,nonatomic) AMMapAnnotaion *myAnnotation;
 @property (nonatomic,strong) UILabel *titleLabel;
 @property (nonatomic,strong) UILabel *detailLabel;
@@ -29,8 +29,10 @@
         self.canShowCallout = NO;
 
         self.myAnnotation = (AMMapAnnotaion *)annotation;
-        self.calloutView = [[UIView alloc] init];
-        self.calloutView.backgroundColor = [UIColor whiteColor];
+        self.calloutView = [[UIControl alloc] init];
+        self.calloutView.backgroundColor = [UIColor colorWithWhite:1 alpha:0.9];
+        [self.calloutView addTarget:self action:@selector(calloutDidClicked:) forControlEvents:UIControlEventTouchUpInside];
+        
     }
     return self;
 }
@@ -63,31 +65,43 @@
     
     UIView *hitView = [super hitTest:point withEvent:event];
     self.tapedCallout = NO;
-    if (self.isSelected) {
-
-        if (hitView) {
-//            self.canDeselected = NO;
-            return self;
+    if (hitView == nil) {
+        for (UIView *subView in self.subviews) {
+            CGPoint position = [self convertPoint:point toView:subView];
+            if (CGRectContainsPoint(subView.bounds, position)) {
+                hitView = subView;
+                self.tapedCallout = YES;
+                break;
+            }
         }
+    }
+    return hitView;
+}
 
-        if (CGRectContainsPoint(self.calloutView.frame, point)) {
-//            hitView = self.calloutView;
-            self.tapedCallout = YES;
-
-            return self.calloutView;
+- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
+    BOOL inside = [super pointInside:point withEvent:event];
+    
+    if (!inside) {
+        for (UIView *subView in self.subviews) {
+            CGPoint position = [self convertPoint:point toView:subView];
+            if (CGRectContainsPoint(subView.bounds, position)) {
+                inside = YES;
+                break;
+            }
         }
-
     }
+    
+    return inside;
+}
 
-    return hitView;
+- (void)calloutDidClicked:(id)sender {
+    if (self.delegate && [self.delegate respondsToSelector:@selector(mapView:didTapAnnotaionCallout:)]) {
+        [self.delegate mapView:[self findMap:self] didTapAnnotaionCallout:self.myAnnotation];
+    }
 }
 
 - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
-    if (self.isSelected && self.tapedCallout) {
-        if (self.delegate && [self.delegate respondsToSelector:@selector(mapView:didTapAnnotaionCallout:)]) {
-            [self.delegate mapView:[self findMap:self] didTapAnnotaionCallout:self.myAnnotation];
-        }
-    }
+    
     [super setSelected:selected animated:YES];
 
     // Get the custom callout view.
@@ -112,7 +126,7 @@
             frame.size.width = w0;
         }
         self.titleLabel.frame = frame;
-        [self.calloutView addSubview:self.titleLabel];
+        [calloutView addSubview:self.titleLabel];
 
         CGFloat w1 = maxWidth;
         self.detailLabel.text = detail;
@@ -125,7 +139,7 @@
             frame.size.width = w1;
         }
         self.detailLabel.frame = frame;
-        [self.calloutView addSubview:self.detailLabel];
+        [calloutView addSubview:self.detailLabel];
 
         CGFloat h = CGRectGetMaxY(frame) + 5 + 10;
 
@@ -177,7 +191,7 @@
 
         CGFloat w = MAX(w0, w1) + 5 * 2;
 
-        self.calloutView.frame = CGRectMake((CGRectGetWidth(frame) - w) * 0.5, -h, w, h);
+        calloutView.frame = CGRectMake((CGRectGetWidth(frame) - w) * 0.5, -h, w, h);
 
         UIBezierPath *path = [self pathForCalloutWithWidth:w Height:h Anchor:CGPointMake(w * 0.5, h)];
 
@@ -186,7 +200,7 @@
         mask.shadowColor = [UIColor blackColor].CGColor;
         mask.shadowOffset = CGSizeMake(2, 2);
         mask.path = path.CGPath;
-        self.calloutView.layer.mask = mask;
+        calloutView.layer.mask = mask;
 
         [self addSubview:calloutView];
     } else {

+ 13 - 0
Apex Mobile/Apex Mobile/AMMapView.h

@@ -0,0 +1,13 @@
+//
+//  AMMapView.h
+//  Apex Mobile
+//
+//  Created by Jack on 2018/5/4.
+//  Copyright © 2018年 United Software Applications, Inc. All rights reserved.
+//
+
+#import <MapKit/MapKit.h>
+
+@interface AMMapView : MKMapView
+
+@end

+ 21 - 0
Apex Mobile/Apex Mobile/AMMapView.m

@@ -0,0 +1,21 @@
+//
+//  AMMapView.m
+//  Apex Mobile
+//
+//  Created by Jack on 2018/5/4.
+//  Copyright © 2018年 United Software Applications, Inc. All rights reserved.
+//
+
+#import "AMMapView.h"
+
+@implementation AMMapView
+
+- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
+    if ([touch.view isKindOfClass:[UIControl class]]) {
+        return NO;
+    }
+    
+    return YES;
+}
+
+@end

+ 129 - 2
Apex Mobile/Apex Mobile/HomeViewController.m

@@ -25,7 +25,7 @@ typedef enum {
     HomeModeKPI = 1
 } HomeMode;
 
-@interface HomeViewController () <UITableViewDelegate,UITableViewDataSource,UISearchBarDelegate,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout,KPIDelegate>
+@interface HomeViewController () <UITableViewDelegate,UITableViewDataSource,UISearchBarDelegate,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout,KPIDelegate,MKMapViewDelegate,ShipCellDelegate>
 
 @property (strong, nonatomic) IBOutlet UISegmentedControl *segmentControl;
 
@@ -75,6 +75,7 @@ typedef enum {
     [self registNotification];
     [self configureTableView];
     self.shipSearchBar.delegate =self;
+    self.mapView.delegate = self;
     
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(logout) name:APLogoutNotification object:nil];
     
@@ -520,7 +521,7 @@ typedef enum {
         NSString *port = [item objectForKey:@"port"];
         NSInteger stage = [[item objectForKey:@"transport_stage"] integerValue];
         
-        [[[[[[[cell setTitle:title] setDescription:desc] setDetail:detail] setPort:port] setTime:date] setIcon:icon] setTransportStage:stage];
+        [[[[[[[[cell setTitle:title] setDescription:desc] setDetail:detail] setPort:port] setTime:date] setIcon:icon] setTransportStage:stage] setDelegate:self];
         
         return cell;
     } else {
@@ -754,4 +755,130 @@ typedef enum {
     }
 }
 
+#pragma mark - Map
+
+- (NSDictionary *)fakeLoaction {
+    NSArray *arr = [ApexMobileDB get_Location];
+    
+    NSMutableDictionary *returnDic = [NSMutableDictionary dictionary];
+    
+    for (int i = 0; i < arr.count ; i ++) {
+        
+        NSDictionary* location = arr[i];
+        NSString* area = [location valueForKey:@"area"];
+        NSString* company = [location valueForKey:@"company"];
+//        NSString* city = [location valueForKey:@"city"];
+        NSString *longitude = [location valueForKey:@"longitude"];
+        NSString *latitude = [location valueForKey:@"latitude"];
+        
+        NSDictionary *dic = @{
+                                   @"addr" : area,
+                                   @"name" : company,
+                                   @"lon" : longitude,
+                                   @"lat" : latitude
+                                   };
+        if (i == 0) {
+            [returnDic setObject:dic forKey:@"pol"];
+        } else if (i == 1) {
+            [returnDic setObject:dic forKey:@"pod"];
+        } else if (i == 2) {
+            [returnDic setObject:dic forKey:@"poe"];
+        } else if (i == 3) {
+            [returnDic setObject:dic forKey:@"por"];
+        } else if (i == 4) {
+            [returnDic setObject:dic forKey:@"origin"];
+        } else if (i == 5) {
+            [returnDic setObject:dic forKey:@"destination"];
+        } else if (i == 6) {
+            [returnDic setObject:dic forKey:@"current"];
+        } else {
+            break;
+        }
+        
+    }
+    
+    return returnDic;
+}
+
+- (void)setSelectedIndexPath:(NSIndexPath *)indexPath {
+    
+    [self.mapView removeAnnotations:self.mapView.annotations];
+    
+    NSDictionary *item = [self.shipArray objectAtIndex:indexPath.section];
+    NSDictionary *locationInfo = [item objectForKey:@"locations"];
+    
+    locationInfo = [self fakeLoaction];
+    
+    // pol,pod,poe,por,origin,destination,current
+    if (locationInfo) {
+        NSDictionary *pol = [locationInfo objectForKey:@"pol"];
+        [self handleLoaction:pol];
+        
+        NSDictionary *pod = [locationInfo objectForKey:@"pod"];
+        [self handleLoaction:pod];
+        
+        NSDictionary *poe = [locationInfo objectForKey:@"poe"];
+        [self handleLoaction:poe];
+        
+        NSDictionary *por = [locationInfo objectForKey:@"por"];
+        [self handleLoaction:por];
+        
+        NSDictionary *origin = [locationInfo objectForKey:@"origin"];
+        [self handleLoaction:origin];
+        
+        NSDictionary *destination = [locationInfo objectForKey:@"destination"];
+        [self handleLoaction:destination];
+        
+        NSDictionary *current = [locationInfo objectForKey:@"current"];
+        [self handleLoaction:current];
+    }
+    
+    
+}
+
+- (void)handleLoaction:(NSDictionary *)location {
+    if (location == nil) {
+        return;
+    }
+    NSString* addr = [location valueForKey:@"addr"];
+    NSString* name = [location valueForKey:@"name"];
+    double longitude = [[location valueForKey:@"lon"] doubleValue];
+    double latitude = [[location valueForKey:@"lat"] doubleValue];
+    
+    // 创建大头针(标注)的数据模型(此处不创建视图,视图通过MKMapView的委托设置回调方法来生成的)
+    MKPointAnnotation *ann = [[MKPointAnnotation alloc] init];
+    CLLocationCoordinate2D c2d = CLLocationCoordinate2DMake(latitude, longitude);
+    // 指定大头针的经纬度坐标(位置)以及附加的信息
+    ann.coordinate = c2d;
+    ann.title = name;
+    ann.subtitle = addr;
+    
+    // 将大头针数据模型添加到MKMapView上管理
+    [self.mapView addAnnotation:ann];
+    
+}
+
+#pragma mark - Map Delegate
+
+// 当地图上添加了标注以后要执行的回调方法
+- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
+    
+//    // 获取可复用的大头针视图
+//    MKAnnotationView *pinView = (id)[mapView dequeueReusableAnnotationViewWithIdentifier:@"PIN"];
+//
+//    if (!pinView) { // 如果没有可重用的大头针视图就创建并指定重用标识
+//        pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"PIN"];
+//    }
+//    pinView.image = [UIImage imageNamed:@"ic_marker"];
+    
+    return nil;
+}
+
+#pragma mark - ShipCell Delegate
+
+- (void)shipCellDidTapIcon:(ShipingStatusCell *)cell {
+    NSIndexPath *indexPath = [self.shipTableView indexPathForCell:cell];
+    [self setSelectedIndexPath:indexPath];
+}
+
 @end

+ 4 - 3
Apex Mobile/Apex Mobile/LocationViewController.m

@@ -13,6 +13,7 @@
 #import <MapKit/MapKit.h>
 #import "AMMapAnnotaion.h"
 #import "AMAnnotationView.h"
+#import "AMMapView.h"
 
 #pragma mark - Button
 
@@ -39,7 +40,7 @@
     GMSMapView *mapView_;
     
     // 苹果原生的地图视图
-    MKMapView *myMapView;
+    AMMapView *myMapView;
     // 定位服务管理器
     CLLocationManager *myLocManager;
 }
@@ -560,7 +561,7 @@ didTapInfoWindowOfMarker:(GMSMarker *)marker
     
     [self updateLocation];
     
-    myMapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
+    myMapView = [[AMMapView alloc] initWithFrame:self.view.bounds];
     // 为MKMapView绑定委托
     myMapView.delegate = self;
     
@@ -648,7 +649,7 @@ didTapInfoWindowOfMarker:(GMSMarker *)marker
         
         // 将大头针数据模型添加到MKMapView上管理
         [myMapView addAnnotation:ann];
-        break;
+//        break;
     }
 }
 

+ 5 - 6
Apex Mobile/Apex Mobile/Main.storyboard

@@ -6,6 +6,7 @@
     <dependencies>
         <deployment version="2304" identifier="iOS"/>
         <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
+        <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
         <capability name="Safe area layout guides" minToolsVersion="9.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
@@ -343,13 +344,10 @@
                                 <rect key="frame" x="0.0" y="104" width="375" height="514"/>
                                 <subviews>
                                     <mapView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" mapType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="NXU-e4-wFa">
-                                        <rect key="frame" x="0.0" y="0.0" width="375" height="150"/>
-                                        <constraints>
-                                            <constraint firstAttribute="height" constant="150" id="eAC-LI-n8J"/>
-                                        </constraints>
+                                        <rect key="frame" x="0.0" y="0.0" width="375" height="171.5"/>
                                     </mapView>
                                     <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="150" width="375" height="514"/>
+                                        <rect key="frame" x="0.0" y="171.5" width="375" height="342.5"/>
                                         <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
                                         <inset key="separatorInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
                                         <connections>
@@ -390,16 +388,17 @@
                                 <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <constraints>
                                     <constraint firstItem="iIl-j9-7oa" firstAttribute="width" secondItem="TYb-wc-Nwg" secondAttribute="width" id="3bU-Ll-nT0"/>
+                                    <constraint firstAttribute="bottom" secondItem="iIl-j9-7oa" secondAttribute="bottom" id="4yV-a1-feP"/>
                                     <constraint firstItem="0Al-V9-YKc" firstAttribute="centerX" secondItem="TYb-wc-Nwg" secondAttribute="centerX" id="8a8-fw-f0B"/>
                                     <constraint firstItem="NXU-e4-wFa" firstAttribute="top" secondItem="TYb-wc-Nwg" secondAttribute="top" id="DQD-M7-57a"/>
                                     <constraint firstItem="iIl-j9-7oa" firstAttribute="centerX" secondItem="TYb-wc-Nwg" secondAttribute="centerX" id="Jd3-gv-peg"/>
                                     <constraint firstItem="NXU-e4-wFa" firstAttribute="leading" secondItem="TYb-wc-Nwg" secondAttribute="leading" id="MUJ-8S-eA6"/>
+                                    <constraint firstItem="NXU-e4-wFa" firstAttribute="height" secondItem="iIl-j9-7oa" secondAttribute="height" multiplier="1:2" id="Ont-ff-Yo7"/>
                                     <constraint firstItem="IFp-NK-v1o" firstAttribute="centerY" secondItem="TYb-wc-Nwg" secondAttribute="centerY" id="Q19-iJ-g2O"/>
                                     <constraint firstAttribute="trailing" secondItem="NXU-e4-wFa" secondAttribute="trailing" id="XQd-lR-G3j"/>
                                     <constraint firstItem="0Al-V9-YKc" firstAttribute="centerY" secondItem="TYb-wc-Nwg" secondAttribute="centerY" id="fYu-3V-T4O"/>
                                     <constraint firstItem="iIl-j9-7oa" firstAttribute="top" secondItem="NXU-e4-wFa" secondAttribute="bottom" id="kfT-Li-zDm"/>
                                     <constraint firstItem="IFp-NK-v1o" firstAttribute="centerX" secondItem="TYb-wc-Nwg" secondAttribute="centerX" id="lcn-AL-YXN"/>
-                                    <constraint firstItem="iIl-j9-7oa" firstAttribute="height" secondItem="TYb-wc-Nwg" secondAttribute="height" id="whL-aN-51R"/>
                                 </constraints>
                             </view>
                             <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3xo-DP-qWN">

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

@@ -8,8 +8,19 @@
 
 #import <UIKit/UIKit.h>
 
+@class ShipingStatusCell;
+@protocol ShipCellDelegate <NSObject>
+
+@optional
+
+- (void)shipCellDidTapIcon:(ShipingStatusCell *)cell;
+
+@end
+
 @interface ShipingStatusCell : UITableViewCell
 
+@property (nonatomic,weak) id<ShipCellDelegate> delegate;
+
 - (instancetype)setTitle:(NSString *)title;
 - (instancetype)setPort:(NSString *)port;
 - (instancetype)setTime:(NSString *)time;

+ 13 - 1
Apex Mobile/Apex Mobile/ShipingStatusCell.m

@@ -42,6 +42,10 @@
     self.descLabel.textColor = [UIColor colorWithRed:53 / 255.0 green:53 / 255.0 blue:55 / 255.0 alpha:1.0];
     
     // Initialization code
+    
+    self.iconView.userInteractionEnabled = YES;
+    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(iconViewDidTaped:)];
+    [self.iconView addGestureRecognizer:tap];
 }
 //- (UIEdgeInsets)layoutMargins {
 //    [super layoutMargins];
@@ -167,7 +171,15 @@
 - (void)prepareForReuse {
     [super prepareForReuse];
     
-    [[[[[[self setTitle:nil] setPort:nil] setTime:nil] setDescription:nil] setDetail:nil] setIcon:nil];
+    [[[[[[[self setTitle:nil] setPort:nil] setTime:nil] setDescription:nil] setDetail:nil] setIcon:nil] setDelegate:nil];
+}
+
+#pragma mark - Action
+
+- (void)iconViewDidTaped:(UITapGestureRecognizer *)tap {
+    if (self.delegate && [self.delegate respondsToSelector:@selector(shipCellDidTapIcon:)]) {
+        [self.delegate shipCellDidTapIcon:self];
+    }
 }
 
 @end