From 3115bc3aa318a6a1ce9534d891ad5255a882526b Mon Sep 17 00:00:00 2001 From: Igor Khmurets Date: Mon, 28 Jul 2014 15:12:17 +0300 Subject: [PATCH] [ios] HTML support in PP --- .../PlacePageBookmarkDescriptionCell.h | 13 ++ .../PlacePageBookmarkDescriptionCell.m | 91 ++++++++++ iphone/Maps/Classes/PlacePageView.mm | 157 +++++++++++++----- iphone/Maps/Maps.xcodeproj/project.pbxproj | 8 + 4 files changed, 232 insertions(+), 37 deletions(-) create mode 100644 iphone/Maps/Classes/PlacePageBookmarkDescriptionCell.h create mode 100644 iphone/Maps/Classes/PlacePageBookmarkDescriptionCell.m diff --git a/iphone/Maps/Classes/PlacePageBookmarkDescriptionCell.h b/iphone/Maps/Classes/PlacePageBookmarkDescriptionCell.h new file mode 100644 index 0000000000..c4b8ad2427 --- /dev/null +++ b/iphone/Maps/Classes/PlacePageBookmarkDescriptionCell.h @@ -0,0 +1,13 @@ + +#import + +@interface PlacePageBookmarkDescriptionCell : UITableViewCell + ++ (CGFloat)cellHeightWithWebViewHeight:(CGFloat)webViewHeight; ++ (CGFloat)cellHeightWithTextValue:(NSString *)text viewWidth:(CGFloat)viewWidth; + + +@property (nonatomic, weak) UIWebView * webView; +@property (nonatomic) UILabel * titleLabel; + +@end diff --git a/iphone/Maps/Classes/PlacePageBookmarkDescriptionCell.m b/iphone/Maps/Classes/PlacePageBookmarkDescriptionCell.m new file mode 100644 index 0000000000..6263f6170a --- /dev/null +++ b/iphone/Maps/Classes/PlacePageBookmarkDescriptionCell.m @@ -0,0 +1,91 @@ + +#import "PlacePageBookmarkDescriptionCell.h" +#import "UIKitCategories.h" + +@implementation PlacePageBookmarkDescriptionCell + +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier +{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + + UIView * selectedBackgroundView = [[UIView alloc] initWithFrame:self.bounds]; + selectedBackgroundView.backgroundColor = [UIColor colorWithWhite:1 alpha:0.2]; + self.selectedBackgroundView = selectedBackgroundView; + + UIImageView * editImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"PlacePageEditButton"]]; + editImageView.center = CGPointMake(self.width - 30, 20); + editImageView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin; + [self addSubview:editImageView]; + + UIImage * separatorImage = [[UIImage imageNamed:@"PlacePageSeparator"] resizableImageWithCapInsets:UIEdgeInsetsZero]; + CGFloat const offset = 12.5; + UIImageView * separator = [[UIImageView alloc] initWithFrame:CGRectMake(offset, self.height - separatorImage.size.height, self.width - 2 * offset, separatorImage.size.height)]; + separator.image = separatorImage; + separator.maxY = self.height; + separator.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin; + [self addSubview:separator]; + + [self addSubview:self.titleLabel]; + + return self; +} + +#define LEFT_SHIFT 20 +#define RIGHT_SHIFT 47 +#define TITLE_FONT [UIFont fontWithName:@"HelveticaNeue-Light" size:17.5] + +- (void)layoutSubviews +{ + self.titleLabel.width = self.width - LEFT_SHIFT - RIGHT_SHIFT; + [self.titleLabel sizeToFit]; + self.titleLabel.origin = CGPointMake(LEFT_SHIFT, 10); + + self.selectedBackgroundView.frame = self.bounds; + self.backgroundColor = [UIColor clearColor]; +} + +- (void)setWebView:(UIWebView *)webView +{ + if (!_webView && !webView.isLoading) + { + [self.contentView addSubview:webView]; + webView.autoresizingMask = UIViewAutoresizingFlexibleWidth; + CGFloat const xOffset = 12; + CGFloat const yOffset = 1; + webView.frame = CGRectMake(xOffset, yOffset, self.width - 2 * xOffset, self.height - 2 * yOffset); + webView.clipsToBounds = YES; + webView.opaque = NO; + webView.backgroundColor = [UIColor clearColor]; + webView.userInteractionEnabled = NO; + _webView = webView; + } +} + ++ (CGFloat)cellHeightWithWebViewHeight:(CGFloat)webViewHeight +{ + return webViewHeight - 5; +} + ++ (CGFloat)cellHeightWithTextValue:(NSString *)text viewWidth:(CGFloat)viewWidth +{ + CGFloat textHeight = [text sizeWithDrawSize:CGSizeMake(viewWidth - LEFT_SHIFT - RIGHT_SHIFT, 10000) font:TITLE_FONT].height; + return textHeight + 24; +} + +- (UILabel *)titleLabel +{ + if (!_titleLabel) + { + _titleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + _titleLabel.backgroundColor = [UIColor clearColor]; + _titleLabel.font = TITLE_FONT; + _titleLabel.textAlignment = NSTextAlignmentLeft; + _titleLabel.numberOfLines = 0; + _titleLabel.lineBreakMode = NSLineBreakByWordWrapping; + _titleLabel.textColor = [UIColor blackColor]; + _titleLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin; + } + return _titleLabel; +} + +@end diff --git a/iphone/Maps/Classes/PlacePageView.mm b/iphone/Maps/Classes/PlacePageView.mm index 0c3015e673..91ce85a172 100644 --- a/iphone/Maps/Classes/PlacePageView.mm +++ b/iphone/Maps/Classes/PlacePageView.mm @@ -9,6 +9,7 @@ #import "PlacePageEditCell.h" #import "PlacePageShareCell.h" #import "PlacePageRoutingCell.h" +#import "PlacePageBookmarkDescriptionCell.h" #include "../../search/result.hpp" #import "ColorPickerView.h" #import "Statistics.h" @@ -18,13 +19,13 @@ typedef NS_ENUM(NSUInteger, CellRow) { CellRowCommon, CellRowSet, - CellRowInfo, + CellRowBookmarkDescription, CellRowShare, CellRowRouting, CellInvalid // Sections changed but rows are not }; -@interface PlacePageView () +@interface PlacePageView () @property (nonatomic) UIImageView * backgroundView; @property (nonatomic) UIView * headerView; @@ -37,11 +38,12 @@ typedef NS_ENUM(NSUInteger, CellRow) @property (nonatomic) UIImageView * editImageView; @property (nonatomic) UIImageView * arrowImageView; @property (nonatomic) UIView * pickerView; +@property (nonatomic) UIWebView * bookmarkDescriptionView; @property (nonatomic) NSString * title; @property (nonatomic) NSString * types; @property (nonatomic) NSString * address; -@property (nonatomic) NSString * info; +@property (nonatomic) NSString * bookmarkDescription; @property (nonatomic) NSString * setName; @property (nonatomic) NSString * temporaryTitle; @@ -55,6 +57,8 @@ typedef NS_ENUM(NSUInteger, CellRow) BookmarkData * m_bookmarkData; size_t m_categoryIndex; BOOL updatingTable; + BOOL needToUpdateWebView; + BOOL webViewIsLoaded; BOOL needUpdateAddressInfo; search::AddressInfo m_addressInfo; @@ -101,8 +105,6 @@ typedef NS_ENUM(NSUInteger, CellRow) CGFloat const defaultHeight = 93; [self updateHeight:defaultHeight]; - updatingTable = NO; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(startMonitoringLocation:) name:LOCATION_MANAGER_STARTED_NOTIFICATION object:nil]; return self; @@ -167,7 +169,7 @@ typedef NS_ENUM(NSUInteger, CellRow) else if (indexPath.row == 1) return [self isBookmark] ? CellRowSet : CellRowShare; else if (indexPath.row == 2) - return [self isBookmark] ? CellRowInfo : CellRowRouting; + return [self isBookmark] ? CellRowBookmarkDescription : CellRowRouting; else if (indexPath.row == 3) return CellRowShare; else if (indexPath.row == 4) @@ -216,13 +218,25 @@ typedef NS_ENUM(NSUInteger, CellRow) cell.titleLabel.text = self.setName; return cell; } - else if (row == CellRowInfo) + else if (row == CellRowBookmarkDescription) { - PlacePageEditCell * cell = [tableView dequeueReusableCellWithIdentifier:[PlacePageEditCell className]]; + PlacePageBookmarkDescriptionCell * cell = [tableView dequeueReusableCellWithIdentifier:[PlacePageBookmarkDescriptionCell className]]; if (!cell) // only for iOS 5 - cell = [[PlacePageEditCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[PlacePageEditCell className]]; - - cell.titleLabel.text = self.info; + cell = [[PlacePageBookmarkDescriptionCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[PlacePageBookmarkDescriptionCell className]]; + if ([self descriptionIsHTML]) + { + cell.webView.hidden = NO; + cell.titleLabel.hidden = YES; + cell.webView = self.bookmarkDescriptionView; + if (!webViewIsLoaded) + [self.bookmarkDescriptionView loadHTMLString:self.bookmarkDescription baseURL:nil]; + } + else + { + cell.titleLabel.hidden = NO; + cell.webView.hidden = YES; + cell.titleLabel.text = self.bookmarkDescription; + } return cell; } else if (row == CellRowShare) @@ -257,8 +271,20 @@ typedef NS_ENUM(NSUInteger, CellRow) return [PlacePageInfoCell cellHeightWithViewWidth:tableView.width inMyPositionMode:[self isMyPosition]]; else if (row == CellRowSet) return [PlacePageEditCell cellHeightWithTextValue:self.setName viewWidth:tableView.width]; - else if (row == CellRowInfo) - return [PlacePageEditCell cellHeightWithTextValue:self.info viewWidth:tableView.width]; + else if (row == CellRowBookmarkDescription) + { + if ([self descriptionIsHTML]) + { + if (self.bookmarkDescriptionView.isLoading) + return 0; + else + return [PlacePageBookmarkDescriptionCell cellHeightWithWebViewHeight:self.bookmarkDescriptionView.height]; + } + else + { + return [PlacePageEditCell cellHeightWithTextValue:self.bookmarkDescription viewWidth:tableView.width]; + } + } else if (row == CellRowShare) return [PlacePageShareCell cellHeight]; else if (row == CellRowRouting) @@ -272,13 +298,28 @@ typedef NS_ENUM(NSUInteger, CellRow) [tableView deselectRowAtIndexPath:indexPath animated:YES]; if (row == CellRowSet) [self.delegate placePageView:self willEditProperty:@"Set" inBookmarkAndCategory:GetFramework().FindBookmark([self userMark])]; - else if (row == CellRowInfo) + else if (row == CellRowBookmarkDescription) [self.delegate placePageView:self willEditProperty:@"Description" inBookmarkAndCategory:GetFramework().FindBookmark([self userMark])]; } #define TITLE_LABEL_LEFT_OFFSET 20 #define TYPES_LABEL_LANDSCAPE_RIGHT_OFFSET 80 +- (void)webViewDidFinishLoad:(UIWebView *)webView +{ + webViewIsLoaded = YES; + if (updatingTable) + needToUpdateWebView = YES; + else + [self updateWebView]; +} + +- (void)updateWebView +{ + [self.bookmarkDescriptionView sizeToFit]; + [self layoutSubviews]; +} + - (void)reloadHeader { self.titleLabel.text = self.title; @@ -430,21 +471,19 @@ typedef NS_ENUM(NSUInteger, CellRow) { self.tableView.alpha = 1; self.titleLabel.userInteractionEnabled = YES; - CGFloat const infoCellHeight = [PlacePageInfoCell cellHeightWithViewWidth:self.tableView.width inMyPositionMode:[self isMyPosition]]; - CGFloat fullHeight = headerHeight + infoCellHeight + [PlacePageShareCell cellHeight] + (GetFramework().IsRoutingEnabled() ? [PlacePageRoutingCell cellHeight] : 0); - if ([self isBookmark]) - { - fullHeight += [PlacePageEditCell cellHeightWithTextValue:self.setName viewWidth:self.tableView.width]; - fullHeight += [PlacePageEditCell cellHeightWithTextValue:self.info viewWidth:self.tableView.width]; - } - fullHeight = MIN(fullHeight + 20, [self maxHeight]); self.headerSeparator.maxY = headerHeight; [UIView animateWithDuration:(animated ? 0.4 : 0) delay:0 damping:damping initialVelocity:0 options:options animations:^{ self.arrowImageView.alpha = 0; - [self updateHeight:fullHeight]; + [self updateHeight:[self fullHeight]]; self.minY = [self viewMinY]; self.headerSeparator.alpha = 1; - } completion:nil]; + } completion:^(BOOL finished) { + if (needToUpdateWebView) + { + needToUpdateWebView = NO; + [self updateWebView]; + } + }]; } else if (self.state == PlacePageStateHidden) { @@ -457,6 +496,23 @@ typedef NS_ENUM(NSUInteger, CellRow) [self updateBookmarkViewsAlpha:animated]; } +- (CGFloat)fullHeight +{ + CGFloat const infoCellHeight = [PlacePageInfoCell cellHeightWithViewWidth:self.tableView.width inMyPositionMode:[self isMyPosition]]; + CGFloat fullHeight = [self headerHeight] + infoCellHeight + [PlacePageShareCell cellHeight] + (GetFramework().IsRoutingEnabled() ? [PlacePageRoutingCell cellHeight] : 0); + if ([self isBookmark]) + { + fullHeight += [PlacePageEditCell cellHeightWithTextValue:self.setName viewWidth:self.tableView.width]; + if ([self descriptionIsHTML]) + fullHeight += [PlacePageBookmarkDescriptionCell cellHeightWithWebViewHeight:self.bookmarkDescriptionView.height]; + else + fullHeight += [PlacePageEditCell cellHeightWithTextValue:self.bookmarkDescription viewWidth:self.tableView.width]; + } + fullHeight = MIN(fullHeight + 20, [self maxHeight]); + + return fullHeight; +} + - (void)updateBookmarkViewsAlpha:(BOOL)animated { self.editImageView.center = CGPointMake(self.titleLabel.maxX + 14, self.titleLabel.minY + 11.5); @@ -481,15 +537,12 @@ typedef NS_ENUM(NSUInteger, CellRow) { if ([self isBookmark]) { - CGFloat newHeight = self.backgroundView.height + [PlacePageEditCell cellHeightWithTextValue:self.info viewWidth:self.tableView.width] + [PlacePageEditCell cellHeightWithTextValue:self.setName viewWidth:self.tableView.width]; - newHeight = MIN(newHeight, [self maxHeight]); CGFloat const headerHeight = [self headerHeight]; - self.tableView.frame = CGRectMake(0, headerHeight, self.superview.width, newHeight - headerHeight - BOTTOM_SHADOW_OFFSET); + CGFloat const fullHeight = [self fullHeight]; + self.tableView.frame = CGRectMake(0, headerHeight, self.superview.width, fullHeight - headerHeight - BOTTOM_SHADOW_OFFSET); } -// [self performAfterDelay:0 block:^{ - [self resizeTableAnimated:animated]; -// }]; + [self resizeTableAnimated:animated]; } - (void)resizeTableAnimated:(BOOL)animated @@ -524,9 +577,27 @@ typedef NS_ENUM(NSUInteger, CellRow) } } +- (BOOL)descriptionIsHTML +{ + NSString * description = self.bookmarkDescription; + NSInteger const length = [description length]; + + NSInteger openedCount = 0; + NSInteger closedCount = 0; + for (NSInteger i = 0; i < length; i++) + { + unichar const symbol = [description characterAtIndex:i]; + if (symbol == '<') + openedCount++; + else if (symbol == '>') + closedCount++; + } + return openedCount == closedCount && openedCount != 0; +} + - (CGFloat)maxHeight { - return IPAD ? 600 : (self.superview.width > self.superview.height ? 270 : 470); + return IPAD ? 600 : (self.superview.width > self.superview.height ? 270 : 460); } - (void)didMoveToSuperview @@ -709,8 +780,10 @@ typedef NS_ENUM(NSUInteger, CellRow) _types = nil; _address = nil; _setName = nil; - _info = nil; + _bookmarkDescription = nil; needUpdateAddressInfo = YES; + needToUpdateWebView = NO; + webViewIsLoaded = NO; } - (void)showUserMark:(UserMarkCopy *)mark @@ -859,22 +932,22 @@ typedef NS_ENUM(NSUInteger, CellRow) return _setName; } -- (NSString *)info +- (NSString *)bookmarkDescription { - if (!_info) + if (!_bookmarkDescription) { if ([self isBookmark]) { Bookmark const * bookmark = static_cast([self userMark]); std::string const & description = bookmark->GetDescription(); - _info = description.empty() ? NSLocalizedString(@"description", nil) : [NSString stringWithUTF8String:description.c_str()]; + _bookmarkDescription = description.empty() ? NSLocalizedString(@"description", nil) : [NSString stringWithUTF8String:description.c_str()]; } else { - _info = @""; + _bookmarkDescription = @""; } } - return _info; + return _bookmarkDescription; } - (NSString *)address @@ -1166,6 +1239,16 @@ typedef NS_ENUM(NSUInteger, CellRow) return _arrowImageView; } +- (UIWebView *)bookmarkDescriptionView +{ + if (!_bookmarkDescriptionView) + { + _bookmarkDescriptionView = [[UIWebView alloc] initWithFrame:CGRectZero]; + _bookmarkDescriptionView.delegate = self; + } + return _bookmarkDescriptionView; +} + - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj index 2c80877ce7..ec93ed69ab 100644 --- a/iphone/Maps/Maps.xcodeproj/project.pbxproj +++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj @@ -50,6 +50,8 @@ 97719D491843B6F700BDD815 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97719D471843B6F200BDD815 /* Security.framework */; }; 97719D4B1843B86700BDD815 /* Main_iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97719D4A1843B86700BDD815 /* Main_iPad.storyboard */; }; 97719D4C1843B86700BDD815 /* Main_iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97719D4A1843B86700BDD815 /* Main_iPad.storyboard */; }; + 9773DB8F198652E600C4A9E9 /* PlacePageBookmarkDescriptionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 9773DB8E198652E600C4A9E9 /* PlacePageBookmarkDescriptionCell.m */; }; + 9773DB90198652E600C4A9E9 /* PlacePageBookmarkDescriptionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 9773DB8E198652E600C4A9E9 /* PlacePageBookmarkDescriptionCell.m */; }; 9778E99D191A5B6600AD850A /* BookmarkDescriptionVC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9778E99C191A5B6600AD850A /* BookmarkDescriptionVC.mm */; }; 9778E99E191A5B6600AD850A /* BookmarkDescriptionVC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9778E99C191A5B6600AD850A /* BookmarkDescriptionVC.mm */; }; 9778E9A1191A663700AD850A /* BookmarkNameVC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9778E9A0191A663700AD850A /* BookmarkNameVC.mm */; }; @@ -1388,6 +1390,8 @@ 97719D441843B6DC00BDD815 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; }; 97719D471843B6F200BDD815 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 97719D4A1843B86700BDD815 /* Main_iPad.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main_iPad.storyboard; sourceTree = ""; }; + 9773DB8D198652E600C4A9E9 /* PlacePageBookmarkDescriptionCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlacePageBookmarkDescriptionCell.h; sourceTree = ""; }; + 9773DB8E198652E600C4A9E9 /* PlacePageBookmarkDescriptionCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlacePageBookmarkDescriptionCell.m; sourceTree = ""; }; 9778E99B191A5B6600AD850A /* BookmarkDescriptionVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BookmarkDescriptionVC.h; sourceTree = ""; }; 9778E99C191A5B6600AD850A /* BookmarkDescriptionVC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BookmarkDescriptionVC.mm; sourceTree = ""; }; 9778E99F191A663700AD850A /* BookmarkNameVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BookmarkNameVC.h; sourceTree = ""; }; @@ -2492,6 +2496,8 @@ 97AA2820190AD21100AE1AAB /* PlacePageShareCell.m */, 97354B63196AF97200352536 /* PlacePageRoutingCell.h */, 97354B64196AF97200352536 /* PlacePageRoutingCell.m */, + 9773DB8D198652E600C4A9E9 /* PlacePageBookmarkDescriptionCell.h */, + 9773DB8E198652E600C4A9E9 /* PlacePageBookmarkDescriptionCell.m */, ); name = Cells; sourceTree = ""; @@ -4539,6 +4545,7 @@ 978F9244183B660F000D6C7C /* SwitchCell.m in Sources */, EDB811A3175E1A9C00E36BF2 /* TwoButtonsView.m in Sources */, 97508423199522D300A7457D /* SettingsAndMoreVC.mm in Sources */, + 9773DB8F198652E600C4A9E9 /* PlacePageBookmarkDescriptionCell.m in Sources */, 97ABBA4518C8DF620079333C /* PlacePageView.mm in Sources */, 97F61794183E7445009919E2 /* LinkCell.m in Sources */, 97D092B1190A681F00FF645B /* PlacePageInfoCell.mm in Sources */, @@ -4612,6 +4619,7 @@ 978F9245183B660F000D6C7C /* SwitchCell.m in Sources */, EDB811A4175E1A9C00E36BF2 /* TwoButtonsView.m in Sources */, 97508424199522D300A7457D /* SettingsAndMoreVC.mm in Sources */, + 9773DB90198652E600C4A9E9 /* PlacePageBookmarkDescriptionCell.m in Sources */, 97F61795183E7445009919E2 /* LinkCell.m in Sources */, EDC5C544175F2CA600420E92 /* ShareActionSheet.mm in Sources */, 9778E9A6191A86D800AD850A /* SelectedColorView.m in Sources */,