[ios] Added bookmarks by single tap

This commit is contained in:
Alex Zolotarev 2012-04-02 13:42:55 +03:00 committed by Alex Zolotarev
parent d8aaeaa4a3
commit a833955aa0
11 changed files with 198 additions and 0 deletions

View file

@ -0,0 +1,17 @@
#import <UIKit/UIKit.h>
@interface BalloonView : NSObject
{
UIImageView * m_pinView;
UIImageView * m_buttonsView;
id m_target;
SEL m_selector;
}
@property(nonatomic,assign,readonly) BOOL isDisplayed;
- (id) initWithTarget:(id)target andSelector:(SEL)selector;
- (void) showInView:(UIView *)view atPoint:(CGPoint)pt;
- (void) hide;
@end

View file

@ -0,0 +1,86 @@
#import "BalloonView.h"
#import <QuartzCore/CALayer.h>
@implementation BalloonView
@synthesize isDisplayed;
- (id) initWithTarget:(id)target andSelector:(SEL)selector;
{
if ((self = [super init]))
{
isDisplayed = NO;
m_target = target;
m_selector = selector;
}
return self;
}
- (void) dealloc
{
[m_buttonsView release];
[m_pinView release];
[super dealloc];
}
- (void) showButtonsInView:(UIView *)view atPoint:(CGPoint)pt
{
m_buttonsView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"star"]];
CGFloat const w = m_buttonsView.bounds.size.width;
CGFloat const h = m_buttonsView.bounds.size.height;
m_buttonsView.frame = CGRectMake(pt.x - w/2, pt.y, w, 0);
m_buttonsView.userInteractionEnabled = YES;
UITapGestureRecognizer * recognizer = [[UITapGestureRecognizer alloc] initWithTarget:m_target action:m_selector];
recognizer.numberOfTapsRequired = 1;
recognizer.numberOfTouchesRequired = 1;
recognizer.delaysTouchesBegan = YES;
[m_buttonsView addGestureRecognizer:recognizer];
[recognizer release];
[view addSubview:m_buttonsView];
// Animate buttons view to appear up from the pin
[UIView transitionWithView:m_buttonsView duration:0.1 options:UIViewAnimationOptionCurveEaseIn
animations:^{
m_buttonsView.frame = CGRectMake(pt.x - w/2, pt.y - h, w, h);
} completion:nil];
}
- (void) showInView:(UIView *)view atPoint:(CGPoint)pt
{
if (isDisplayed)
{
NSLog(@"Already displaying the BalloonView");
return;
}
isDisplayed = YES;
m_pinView = [[UIImageView alloc ]initWithImage:[UIImage imageNamed:@"marker"]];
CGFloat const w = m_pinView.bounds.size.width;
CGFloat const h = m_pinView.bounds.size.height;
// Set initial frame at the top outside of the view
m_pinView.frame = CGRectMake(pt.x - w/2, 0 - h, w, h);
//pinView.userInteractionEnabled = YES;
[view addSubview:m_pinView];
// Animate pin to the touched point
[UIView transitionWithView:m_pinView duration:0.1 options:UIViewAnimationOptionCurveEaseIn
animations:^{ m_pinView.frame = CGRectMake(pt.x - w/2, pt.y - h, w, h); }
completion:^(BOOL){
[self showButtonsInView:view atPoint:CGPointMake(pt.x, pt.y - h)];
}];
}
- (void) hide
{
[m_buttonsView removeFromSuperview];
[m_buttonsView release];
m_buttonsView = nil;
[m_pinView removeFromSuperview];
[m_pinView release];
m_pinView = nil;
isDisplayed = NO;
}
@end

View file

@ -4,6 +4,8 @@
#include "../../geometry/point2d.hpp"
#include "../../geometry/rect2d.hpp"
@class BalloonView;
@interface MapViewController : UIViewController <LocationObserver>
{
enum Action
@ -17,6 +19,7 @@
size_t m_StickyThreshold;
m2::PointD m_Pt1, m_Pt2;
BalloonView * m_bookmark;
}
- (void) ZoomToRect: (m2::RectD const &) rect;

View file

@ -2,6 +2,7 @@
#import "SearchVC.h"
#import "MapsAppDelegate.h"
#import "EAGLView.h"
#import "BalloonView.h"
#import "../Settings/SettingsManager.h"
#import "../../Common/CustomAlertView.h"
@ -104,8 +105,24 @@ Framework * m_framework = NULL;
[searchVC release];
}
- (void)onBookmarkClicked
{
m_framework->AddBookmark(m_Pt1);
[m_bookmark hide];
m_framework->Invalidate();
}
- (void)onSingleTap:(NSValue *)point
{
if (m_bookmark.isDisplayed)
[m_bookmark hide];
else
[m_bookmark showInView:self.view atPoint:[point CGPointValue]];
}
- (void) dealloc
{
[m_bookmark release];
delete m_framework;
[super dealloc];
}
@ -114,6 +131,9 @@ Framework * m_framework = NULL;
{
if ((self = [super initWithCoder:coder]))
{
// Helper to display/hide pin on screen tap
m_bookmark = [[BalloonView alloc] initWithTarget:self andSelector:@selector(onBookmarkClicked)];
// cyclic dependence, @TODO refactor.
// Here we're creating view and window handle in it, and later we should pass framework to the view
EAGLView * v = (EAGLView *)self.view;
@ -190,6 +210,10 @@ NSInteger compareAddress(id l, id r, void * context)
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
// To cancel single tap timer
if (((UITouch *)[touches anyObject]).tapCount > 1)
[NSObject cancelPreviousPerformRequestsWithTarget:self];
[self updatePointsFromEvent:event];
if ([[event allTouches] count] == 1)
@ -218,7 +242,11 @@ NSInteger compareAddress(id l, id r, void * context)
if (m_isSticking)
{
if ((TempPt1.Length(m_Pt1) > m_StickyThreshold) || (TempPt2.Length(m_Pt2) > m_StickyThreshold))
{
m_isSticking = false;
// Hide bookmark icon, if finger has moved
[m_bookmark hide];
}
else
{
/// Still stickying. Restoring old points and return.
@ -258,10 +286,22 @@ NSInteger compareAddress(id l, id r, void * context)
int const touchesCount = [[event allTouches] count];
if (tapCount == 2 && touchesCount == 1 && m_isSticking)
{
// Hide bookmarks icon if it was displayed
[m_bookmark hide];
m_framework->ScaleToPoint(ScaleToPointEvent(m_Pt1.x, m_Pt1.y, 2.0));
}
if (touchesCount == 2 && tapCount == 1 && m_isSticking)
{
// Hide bookmarks icon if it was displayed
[m_bookmark hide];
m_framework->Scale(0.5);
}
// Launch single tap timer
if (touchesCount == 1 && tapCount == 1 && m_isSticking)
[self performSelector:@selector(onSingleTap:) withObject:[NSValue valueWithCGPoint:[theTouch locationInView:self.view]] afterDelay:0.3];
}
- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event

View file

@ -64,6 +64,8 @@
FA09E01113F71F6C007E69CA /* SearchVC.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA09E01013F71F6C007E69CA /* SearchVC.mm */; };
FA0B7E631487747B00CAB3F2 /* GetActiveConnectionType.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7E621487747B00CAB3F2 /* GetActiveConnectionType.mm */; };
FA0E845E138554CF008CEABB /* languages.txt in Resources */ = {isa = PBXBuildFile; fileRef = FA0E845D138554CF008CEABB /* languages.txt */; };
FA1371941525DDBC00E912C9 /* BalloonView.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA1371931525DDBC00E912C9 /* BalloonView.mm */; };
FA1371951525DDBC00E912C9 /* BalloonView.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA1371931525DDBC00E912C9 /* BalloonView.mm */; };
FA1FB8A1147E8CA50052848B /* downloader-highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = FA1FB89B147E8CA50052848B /* downloader-highlighted.png */; };
FA1FB8A2147E8CA50052848B /* downloader-highlighted@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FA1FB89C147E8CA50052848B /* downloader-highlighted@2x.png */; };
FA1FB8A3147E8CA50052848B /* location-highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = FA1FB89D147E8CA50052848B /* location-highlighted.png */; };
@ -81,6 +83,18 @@
FA4B0A16151372BA00758203 /* countries.txt.nosearch in Resources */ = {isa = PBXBuildFile; fileRef = FA4B0A15151372BA00758203 /* countries.txt.nosearch */; };
FA500588128907F0002961F0 /* visibility.txt in Resources */ = {isa = PBXBuildFile; fileRef = FA500587128907F0002961F0 /* visibility.txt */; };
FA64D9A913F975AD00350ECF /* types.txt in Resources */ = {isa = PBXBuildFile; fileRef = FA64D9A813F975AD00350ECF /* types.txt */; };
FA68E15C1525F8F400077B9E /* marker.png in Resources */ = {isa = PBXBuildFile; fileRef = FA68E1581525F8F400077B9E /* marker.png */; };
FA68E15D1525F8F400077B9E /* marker.png in Resources */ = {isa = PBXBuildFile; fileRef = FA68E1581525F8F400077B9E /* marker.png */; };
FA68E15E1525F8F400077B9E /* marker@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FA68E1591525F8F400077B9E /* marker@2x.png */; };
FA68E15F1525F8F400077B9E /* marker@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FA68E1591525F8F400077B9E /* marker@2x.png */; };
FA68E1601525F8F400077B9E /* star.png in Resources */ = {isa = PBXBuildFile; fileRef = FA68E15A1525F8F400077B9E /* star.png */; };
FA68E1611525F8F400077B9E /* star.png in Resources */ = {isa = PBXBuildFile; fileRef = FA68E15A1525F8F400077B9E /* star.png */; };
FA68E1621525F8F400077B9E /* star@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FA68E15B1525F8F400077B9E /* star@2x.png */; };
FA68E1631525F8F400077B9E /* star@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FA68E15B1525F8F400077B9E /* star@2x.png */; };
FA68E1671525F92700077B9E /* Default-Landscape@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FA68E1651525F92700077B9E /* Default-Landscape@2x.png */; };
FA68E1681525F92700077B9E /* Default-Landscape@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FA68E1651525F92700077B9E /* Default-Landscape@2x.png */; };
FA68E1691525F92700077B9E /* Default-Portrait@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FA68E1661525F92700077B9E /* Default-Portrait@2x.png */; };
FA68E16A1525F92700077B9E /* Default-Portrait@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FA68E1661525F92700077B9E /* Default-Portrait@2x.png */; };
FA81AE3314D061BF00A0D70D /* SearchCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA81AE3214D061BF00A0D70D /* SearchCell.mm */; };
FA85F633145DDDC20090E1A0 /* packed_polygons.bin in Resources */ = {isa = PBXBuildFile; fileRef = FA85F632145DDDC20090E1A0 /* packed_polygons.bin */; };
FA87151B12B1518F00592DAF /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA87151A12B1518F00592DAF /* SystemConfiguration.framework */; };
@ -1313,6 +1327,8 @@
FA09E01013F71F6C007E69CA /* SearchVC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SearchVC.mm; sourceTree = "<group>"; };
FA0B7E621487747B00CAB3F2 /* GetActiveConnectionType.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GetActiveConnectionType.mm; sourceTree = "<group>"; };
FA0E845D138554CF008CEABB /* languages.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = languages.txt; path = ../../data/languages.txt; sourceTree = SOURCE_ROOT; };
FA1371921525DDBC00E912C9 /* BalloonView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BalloonView.h; sourceTree = "<group>"; };
FA1371931525DDBC00E912C9 /* BalloonView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BalloonView.mm; sourceTree = "<group>"; };
FA1FB89B147E8CA50052848B /* downloader-highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "downloader-highlighted.png"; sourceTree = "<group>"; };
FA1FB89C147E8CA50052848B /* downloader-highlighted@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "downloader-highlighted@2x.png"; sourceTree = "<group>"; };
FA1FB89D147E8CA50052848B /* location-highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "location-highlighted.png"; sourceTree = "<group>"; };
@ -1334,6 +1350,12 @@
FA4B0A15151372BA00758203 /* countries.txt.nosearch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = countries.txt.nosearch; path = ../../data/countries.txt.nosearch; sourceTree = "<group>"; };
FA500587128907F0002961F0 /* visibility.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = visibility.txt; path = ../../data/visibility.txt; sourceTree = SOURCE_ROOT; };
FA64D9A813F975AD00350ECF /* types.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = types.txt; path = ../../data/types.txt; sourceTree = SOURCE_ROOT; };
FA68E1581525F8F400077B9E /* marker.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = marker.png; sourceTree = "<group>"; };
FA68E1591525F8F400077B9E /* marker@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "marker@2x.png"; sourceTree = "<group>"; };
FA68E15A1525F8F400077B9E /* star.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = star.png; sourceTree = "<group>"; };
FA68E15B1525F8F400077B9E /* star@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "star@2x.png"; sourceTree = "<group>"; };
FA68E1651525F92700077B9E /* Default-Landscape@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape@2x.png"; sourceTree = "<group>"; };
FA68E1661525F92700077B9E /* Default-Portrait@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait@2x.png"; sourceTree = "<group>"; };
FA81AE3114D061BF00A0D70D /* SearchCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchCell.h; sourceTree = "<group>"; };
FA81AE3214D061BF00A0D70D /* SearchCell.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SearchCell.mm; sourceTree = "<group>"; };
FA85F632145DDDC20090E1A0 /* packed_polygons.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = packed_polygons.bin; path = ../../data/packed_polygons.bin; sourceTree = SOURCE_ROOT; };
@ -1969,6 +1991,8 @@
080E96DDFE201D6D7F000001 /* Classes */ = {
isa = PBXGroup;
children = (
FA1371921525DDBC00E912C9 /* BalloonView.h */,
FA1371931525DDBC00E912C9 /* BalloonView.mm */,
FA09E00F13F71F6C007E69CA /* SearchVC.h */,
FA09E01013F71F6C007E69CA /* SearchVC.mm */,
EE7F297C1219ECA300EB67A9 /* RenderBuffer.hpp */,
@ -2036,6 +2060,10 @@
29B97317FDCFA39411CA2CEA /* Resources */ = {
isa = PBXGroup;
children = (
FA68E1581525F8F400077B9E /* marker.png */,
FA68E1591525F8F400077B9E /* marker@2x.png */,
FA68E15A1525F8F400077B9E /* star.png */,
FA68E15B1525F8F400077B9E /* star@2x.png */,
FAA3A86B151279D700C7904C /* 29-lite.png */,
FAA3A86C151279D700C7904C /* 50-lite.png */,
FAA3A86D151279D800C7904C /* 57-lite.png */,
@ -2128,6 +2156,8 @@
FA065FEB128614C300FEA989 /* Resources-iPad */ = {
isa = PBXGroup;
children = (
FA68E1651525F92700077B9E /* Default-Landscape@2x.png */,
FA68E1661525F92700077B9E /* Default-Portrait@2x.png */,
FA0660011286168700FEA989 /* Default-Portrait.png */,
FA0660021286168700FEA989 /* Default-Landscape.png */,
FA065FEC128614C400FEA989 /* MainWindow-iPad.xib */,
@ -3384,6 +3414,12 @@
FAA3A8671512799C00C7904C /* 100-pro.png in Resources */,
FAA3A8681512799C00C7904C /* 114-pro.png in Resources */,
FAA3A86A1512799C00C7904C /* 144-pro.png in Resources */,
FA68E15C1525F8F400077B9E /* marker.png in Resources */,
FA68E15E1525F8F400077B9E /* marker@2x.png in Resources */,
FA68E1601525F8F400077B9E /* star.png in Resources */,
FA68E1621525F8F400077B9E /* star@2x.png in Resources */,
FA68E1671525F92700077B9E /* Default-Landscape@2x.png in Resources */,
FA68E1691525F92700077B9E /* Default-Portrait@2x.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3966,6 +4002,12 @@
FAA3A87A151279DE00C7904C /* 144-lite.png in Resources */,
FA4B0A1415136C4C00758203 /* World.mwm.nosearch in Resources */,
FA4B0A16151372BA00758203 /* countries.txt.nosearch in Resources */,
FA68E15D1525F8F400077B9E /* marker.png in Resources */,
FA68E15F1525F8F400077B9E /* marker@2x.png in Resources */,
FA68E1611525F8F400077B9E /* star.png in Resources */,
FA68E1631525F8F400077B9E /* star@2x.png in Resources */,
FA68E1681525F92700077B9E /* Default-Landscape@2x.png in Resources */,
FA68E16A1525F92700077B9E /* Default-Portrait@2x.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -4024,6 +4066,7 @@
FAEC232B1501299500E024BF /* SearchSuggestionsCell.mm in Sources */,
F74243241520CAAE004D9D1E /* BookmarksVC.mm in Sources */,
F7B90CD31521E6D200C054EE /* CustomNavigationView.mm in Sources */,
FA1371941525DDBC00E912C9 /* BalloonView.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -4050,6 +4093,7 @@
FAFB08F9151215EE0041901D /* SearchSuggestionsCell.mm in Sources */,
F74243251520CAAE004D9D1E /* BookmarksVC.mm in Sources */,
F7B90CD41521E6D200C054EE /* CustomNavigationView.mm in Sources */,
FA1371951525DDBC00E912C9 /* BalloonView.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

BIN
iphone/Maps/marker.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
iphone/Maps/marker@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
iphone/Maps/star.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
iphone/Maps/star@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

View file

@ -184,6 +184,13 @@ void Framework::RemoveLocalMaps()
m_model.RemoveAllCountries();
}
void Framework::AddBookmark(m2::PointD const & pixelCoords)
{
// @TODO automatically get bookmark name from the data
string const name = "Best offline maps!";
m_bookmarks.push_back(Bookmark(m_navigator.Screen().PtoG(m_navigator.ShiftPoint(pixelCoords)), name));
}
void Framework::AddBookmark(m2::PointD const & pt, string const & name)
{
m_bookmarks.push_back(Bookmark(pt, name));

View file

@ -124,6 +124,7 @@ public:
void AddLocalMaps();
void RemoveLocalMaps();
void AddBookmark(m2::PointD const & pixelCoords);
void AddBookmark(m2::PointD const & pt, string const & name);
inline size_t BookmarksCount() const { return m_bookmarks.size(); }
void GetBookmark(size_t i, Bookmark & bm) const;