├── .gitignore ├── IQStickerView ├── IQStickerView.h ├── IQStickerView.m ├── close.png ├── resize.png └── rotate_scale.png ├── LICENSE ├── README.md ├── StickerView.xcodeproj └── project.pbxproj ├── StickerView ├── AppDelegate.h ├── AppDelegate.m ├── Default-568h@2x.png ├── Default.png ├── Default@2x.png ├── StickerView-Info.plist ├── StickerView-Prefix.pch ├── ViewController.h ├── ViewController.m ├── en.lproj │ ├── InfoPlist.strings │ └── ViewController.xib └── main.m ├── sample1.jpeg └── sample2.jpeg /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | *.xcworkspace 13 | !default.xcworkspace 14 | xcuserdata 15 | profile 16 | *.moved-aside 17 | DerivedData 18 | .idea/ 19 | -------------------------------------------------------------------------------- /IQStickerView/IQStickerView.h: -------------------------------------------------------------------------------- 1 | // 2 | // IQStickerView.h 3 | // Created by Iftekhar Qurashi on 15/08/13. 4 | 5 | #import 6 | 7 | @protocol IQStickerViewDelegate; 8 | 9 | @interface IQStickerView : UIView 10 | { 11 | UIImageView *resizeView; 12 | UIImageView *rotateView; 13 | UIImageView *closeView; 14 | 15 | BOOL _isShowingEditingHandles; 16 | } 17 | 18 | @property (assign, nonatomic) UIView *contentView; 19 | @property (unsafe_unretained) id delegate; 20 | 21 | @property(nonatomic, assign) BOOL showContentShadow; //Default is YES. 22 | @property(nonatomic, assign) BOOL enableClose; // default is YES. if set to NO, user can't delete the view 23 | @property(nonatomic, assign) BOOL enableResize; // default is YES. if set to NO, user can't Resize the view 24 | @property(nonatomic, assign) BOOL enableRotate; // default is YES. if set to NO, user can't Rotate the view 25 | 26 | //Give call's to refresh. If SuperView is UIScrollView. And it changes it's zoom scale. 27 | -(void)refresh; 28 | 29 | - (void)hideEditingHandles; 30 | - (void)showEditingHandles; 31 | 32 | @end 33 | 34 | @protocol IQStickerViewDelegate 35 | @optional 36 | - (void)stickerViewDidBeginEditing:(IQStickerView *)sticker; 37 | - (void)stickerViewDidChangeEditing:(IQStickerView *)sticker; 38 | - (void)stickerViewDidEndEditing:(IQStickerView *)sticker; 39 | 40 | - (void)stickerViewDidClose:(IQStickerView *)sticker; 41 | 42 | - (void)stickerViewDidShowEditingHandles:(IQStickerView *)sticker; 43 | - (void)stickerViewDidHideEditingHandles:(IQStickerView *)sticker; 44 | @end 45 | 46 | 47 | -------------------------------------------------------------------------------- /IQStickerView/IQStickerView.m: -------------------------------------------------------------------------------- 1 | // 2 | // IQStickerView.m 3 | // Created by Iftekhar Qurashi on 15/08/13. 4 | 5 | #import "IQStickerView.h" 6 | #import 7 | 8 | CG_INLINE CGPoint CGRectGetCenter(CGRect rect) 9 | { 10 | return CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); 11 | } 12 | 13 | CG_INLINE CGPoint CGPointRorate(CGPoint point, CGPoint basePoint, CGFloat angle) 14 | { 15 | CGFloat x = cos(angle) * (point.x-basePoint.x) - sin(angle) * (point.y-basePoint.y) + basePoint.x; 16 | CGFloat y = sin(angle) * (point.x-basePoint.x) + cos(angle) * (point.y-basePoint.y) + basePoint.y; 17 | 18 | return CGPointMake(x,y); 19 | } 20 | 21 | CG_INLINE CGRect CGRectSetCenter(CGRect rect, CGPoint center) 22 | { 23 | return CGRectMake(center.x-CGRectGetWidth(rect)/2, center.y-CGRectGetHeight(rect)/2, CGRectGetWidth(rect), CGRectGetHeight(rect)); 24 | } 25 | 26 | CG_INLINE CGRect CGRectScale(CGRect rect, CGFloat wScale, CGFloat hScale) 27 | { 28 | return CGRectMake(rect.origin.x * wScale, rect.origin.y * hScale, rect.size.width * wScale, rect.size.height * hScale); 29 | } 30 | 31 | CG_INLINE CGFloat CGPointGetDistance(CGPoint point1, CGPoint point2) 32 | { 33 | //Saving Variables. 34 | CGFloat fx = (point2.x - point1.x); 35 | CGFloat fy = (point2.y - point1.y); 36 | 37 | return sqrt((fx*fx + fy*fy)); 38 | } 39 | 40 | CG_INLINE CGFloat CGAffineTransformGetAngle(CGAffineTransform t) 41 | { 42 | return atan2(t.b, t.a); 43 | } 44 | 45 | 46 | CG_INLINE CGSize CGAffineTransformGetScale(CGAffineTransform t) 47 | { 48 | return CGSizeMake(sqrt(t.a * t.a + t.c * t.c), sqrt(t.b * t.b + t.d * t.d)) ; 49 | } 50 | 51 | 52 | static IQStickerView *lastTouchedView; 53 | 54 | @implementation IQStickerView 55 | { 56 | CGFloat _globalInset; 57 | 58 | CGRect initialBounds; 59 | CGFloat initialDistance; 60 | 61 | CGPoint beginningPoint; 62 | CGPoint beginningCenter; 63 | 64 | CGPoint prevPoint; 65 | CGPoint touchLocation; 66 | 67 | CGFloat deltaAngle; 68 | 69 | CGAffineTransform startTransform; 70 | CGRect beginBounds; 71 | } 72 | 73 | @synthesize contentView = _contentView; 74 | @synthesize enableClose = _enableClose; 75 | @synthesize enableResize = _enableResize; 76 | @synthesize enableRotate = _enableRotate; 77 | @synthesize delegate = _delegate; 78 | @synthesize showContentShadow = _showContentShadow; 79 | 80 | -(void)refresh 81 | { 82 | if (self.superview) 83 | { 84 | CGSize scale = CGAffineTransformGetScale(self.superview.transform); 85 | CGAffineTransform t = CGAffineTransformMakeScale(scale.width, scale.height); 86 | [closeView setTransform:CGAffineTransformInvert(t)]; 87 | [resizeView setTransform:CGAffineTransformInvert(t)]; 88 | [rotateView setTransform:CGAffineTransformInvert(t)]; 89 | 90 | if (_isShowingEditingHandles) [_contentView.layer setBorderWidth:1/scale.width]; 91 | else [_contentView.layer setBorderWidth:0.0]; 92 | } 93 | } 94 | 95 | -(void)didMoveToSuperview 96 | { 97 | [super didMoveToSuperview]; 98 | [self refresh]; 99 | } 100 | 101 | - (void)setFrame:(CGRect)newFrame 102 | { 103 | [super setFrame:newFrame]; 104 | [self refresh]; 105 | } 106 | 107 | - (id)initWithFrame:(CGRect)frame 108 | { 109 | /*(1+_globalInset*2)*/ 110 | if (frame.size.width < (1+12*2)) frame.size.width = 25; 111 | if (frame.size.height < (1+12*2)) frame.size.height = 25; 112 | 113 | self = [super initWithFrame:frame]; 114 | if (self) 115 | { 116 | _globalInset = 12; 117 | 118 | // self = [[UIView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)]; 119 | self.backgroundColor = [UIColor clearColor]; 120 | 121 | //Close button view which is in top left corner 122 | closeView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, _globalInset*2, _globalInset*2)]; 123 | [closeView setAutoresizingMask:(UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleBottomMargin)]; 124 | closeView.backgroundColor = [UIColor clearColor]; 125 | closeView.image = [UIImage imageNamed:@"close"]; 126 | closeView.userInteractionEnabled = YES; 127 | [self addSubview:closeView]; 128 | 129 | //Rotating view which is in bottom left corner 130 | rotateView = [[UIImageView alloc]initWithFrame:CGRectMake(self.bounds.size.width-_globalInset*2, self.bounds.size.height-_globalInset*2, _globalInset*2, _globalInset*2)]; 131 | [rotateView setAutoresizingMask:(UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleTopMargin)]; 132 | rotateView.backgroundColor = [UIColor clearColor]; 133 | rotateView.image = [UIImage imageNamed:@"rotate_scale"]; 134 | rotateView.userInteractionEnabled = YES; 135 | [self addSubview:rotateView]; 136 | 137 | //Resizing view which is in bottom right corner 138 | resizeView = [[UIImageView alloc]initWithFrame:CGRectMake(0, self.bounds.size.height-_globalInset*2, _globalInset*2, _globalInset*2)]; 139 | [resizeView setAutoresizingMask:(UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin)]; 140 | resizeView.backgroundColor = [UIColor clearColor]; 141 | resizeView.userInteractionEnabled = YES; 142 | resizeView.image = [UIImage imageNamed:@"resize" ]; 143 | [self addSubview:resizeView]; 144 | 145 | UILongPressGestureRecognizer* moveGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(moveGesture:)]; 146 | [moveGesture setMinimumPressDuration:0.1]; 147 | [self addGestureRecognizer:moveGesture]; 148 | 149 | UITapGestureRecognizer * singleTapShowHide = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(contentTapped:)]; 150 | [self addGestureRecognizer:singleTapShowHide]; 151 | 152 | UITapGestureRecognizer * singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:)]; 153 | [closeView addGestureRecognizer:singleTap]; 154 | 155 | UILongPressGestureRecognizer* panResizeGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(resizeTranslate:)]; 156 | [panResizeGesture setMinimumPressDuration:0]; 157 | [resizeView addGestureRecognizer:panResizeGesture]; 158 | 159 | UILongPressGestureRecognizer* panRotateGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(rotateViewPanGesture:)]; 160 | [panRotateGesture setMinimumPressDuration:0]; 161 | [rotateView addGestureRecognizer:panRotateGesture]; 162 | 163 | [moveGesture requireGestureRecognizerToFail:singleTap]; 164 | 165 | [self setEnableClose:YES]; 166 | [self setEnableResize:YES]; 167 | [self setEnableRotate:YES]; 168 | [self setShowContentShadow:YES]; 169 | 170 | [self hideEditingHandles]; 171 | } 172 | return self; 173 | } 174 | 175 | -(void)contentTapped:(UITapGestureRecognizer*)tapGesture 176 | { 177 | if (_isShowingEditingHandles) 178 | { 179 | [self hideEditingHandles]; 180 | [self.superview bringSubviewToFront:self]; 181 | } 182 | else 183 | [self showEditingHandles]; 184 | } 185 | 186 | -(void)setEnableClose:(BOOL)enableClose 187 | { 188 | _enableClose = enableClose; 189 | [closeView setHidden:!_enableClose]; 190 | [closeView setUserInteractionEnabled:_enableClose]; 191 | } 192 | 193 | -(void)setEnableResize:(BOOL)enableResize 194 | { 195 | _enableResize = enableResize; 196 | [resizeView setHidden:!_enableResize]; 197 | [resizeView setUserInteractionEnabled:_enableResize]; 198 | } 199 | 200 | -(void)setEnableRotate:(BOOL)enableRotate 201 | { 202 | _enableRotate = enableRotate; 203 | [rotateView setHidden:!_enableRotate]; 204 | [rotateView setUserInteractionEnabled:_enableRotate]; 205 | } 206 | 207 | -(void)setShowContentShadow:(BOOL)showContentShadow 208 | { 209 | _showContentShadow = showContentShadow; 210 | 211 | if (_showContentShadow) 212 | { 213 | [self.layer setShadowColor:[UIColor blackColor].CGColor]; 214 | [self.layer setShadowOffset:CGSizeMake(0, 5)]; 215 | [self.layer setShadowOpacity:1.0]; 216 | [self.layer setShadowRadius:4.0]; 217 | } 218 | else 219 | { 220 | [self.layer setShadowColor:[UIColor clearColor].CGColor]; 221 | [self.layer setShadowOffset:CGSizeZero]; 222 | [self.layer setShadowOpacity:0.0]; 223 | [self.layer setShadowRadius:0.0]; 224 | } 225 | } 226 | 227 | - (void)hideEditingHandles 228 | { 229 | lastTouchedView = nil; 230 | 231 | _isShowingEditingHandles = NO; 232 | 233 | if (_enableClose) closeView.hidden = YES; 234 | if (_enableResize) resizeView.hidden = YES; 235 | if (_enableRotate) rotateView.hidden = YES; 236 | 237 | [self refresh]; 238 | 239 | if([_delegate respondsToSelector:@selector(stickerViewDidHideEditingHandles:)]) 240 | [_delegate stickerViewDidHideEditingHandles:self]; 241 | } 242 | 243 | - (void)showEditingHandles 244 | { 245 | [lastTouchedView hideEditingHandles]; 246 | 247 | _isShowingEditingHandles = YES; 248 | 249 | lastTouchedView = self; 250 | 251 | if (_enableClose) closeView.hidden = NO; 252 | if (_enableResize) resizeView.hidden = NO; 253 | if (_enableRotate) rotateView.hidden = NO; 254 | 255 | [self refresh]; 256 | 257 | if([_delegate respondsToSelector:@selector(stickerViewDidShowEditingHandles:)]) 258 | [_delegate stickerViewDidShowEditingHandles:self]; 259 | } 260 | 261 | -(void)setContentView:(UIView *)contentView 262 | { 263 | [_contentView removeFromSuperview]; 264 | 265 | _contentView = contentView; 266 | 267 | _contentView.frame = CGRectInset(self.bounds, _globalInset, _globalInset); 268 | 269 | [_contentView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight)]; 270 | _contentView.backgroundColor = [UIColor clearColor]; 271 | _contentView.layer.borderColor = [[UIColor brownColor]CGColor]; 272 | _contentView.layer.borderWidth = 1.0f; 273 | [self insertSubview:_contentView atIndex:0]; 274 | } 275 | 276 | -(void)singleTap:(UITapGestureRecognizer *)recognizer 277 | { 278 | [self removeFromSuperview]; 279 | 280 | if([_delegate respondsToSelector:@selector(stickerViewDidClose:)]) { 281 | [_delegate stickerViewDidClose:self]; 282 | } 283 | } 284 | 285 | -(void)moveGesture:(UIPanGestureRecognizer *)recognizer 286 | { 287 | touchLocation = [recognizer locationInView:self.superview]; 288 | 289 | if (recognizer.state == UIGestureRecognizerStateBegan) 290 | { 291 | // [lastTouchedView hideEditingHandles]; 292 | beginningPoint = touchLocation; 293 | beginningCenter = self.center; 294 | 295 | [self setCenter:CGPointMake(beginningCenter.x+(touchLocation.x-beginningPoint.x), beginningCenter.y+(touchLocation.y-beginningPoint.y))]; 296 | 297 | beginBounds = self.bounds; 298 | 299 | // [UIView animateWithDuration:0.1 animations:^{ 300 | // [self setBounds:CGRectMake(0, 0, 100, 100)]; 301 | // }]; 302 | 303 | if([_delegate respondsToSelector:@selector(stickerViewDidBeginEditing:)]) 304 | [_delegate stickerViewDidBeginEditing:self]; 305 | } 306 | else if (recognizer.state == UIGestureRecognizerStateChanged) 307 | { 308 | 309 | [self setCenter:CGPointMake(beginningCenter.x+(touchLocation.x-beginningPoint.x), beginningCenter.y+(touchLocation.y-beginningPoint.y))]; 310 | 311 | if([_delegate respondsToSelector:@selector(stickerViewDidChangeEditing:)]) 312 | [_delegate stickerViewDidChangeEditing:self]; 313 | } 314 | else if (recognizer.state == UIGestureRecognizerStateEnded) 315 | { 316 | 317 | [self setCenter:CGPointMake(beginningCenter.x+(touchLocation.x-beginningPoint.x), beginningCenter.y+(touchLocation.y-beginningPoint.y))]; 318 | 319 | // [UIView animateWithDuration:0.1 animations:^{ 320 | // [self setBounds:beginBounds]; 321 | // }]; 322 | 323 | if([_delegate respondsToSelector:@selector(stickerViewDidEndEditing:)]) 324 | [_delegate stickerViewDidEndEditing:self]; 325 | } 326 | 327 | prevPoint = touchLocation; 328 | } 329 | 330 | -(void)resizeTranslate:(UIPanGestureRecognizer *)recognizer 331 | { 332 | touchLocation = [recognizer locationInView:self.superview]; 333 | //Reforming touch location to it's Identity transform. 334 | touchLocation = CGPointRorate(touchLocation, CGRectGetCenter(self.frame), -CGAffineTransformGetAngle(self.transform)); 335 | 336 | if ([recognizer state]== UIGestureRecognizerStateBegan) 337 | { 338 | if([_delegate respondsToSelector:@selector(stickerViewDidBeginEditing:)]) 339 | [_delegate stickerViewDidBeginEditing:self]; 340 | } 341 | else if ([recognizer state] == UIGestureRecognizerStateChanged) 342 | { 343 | CGFloat wChange = (prevPoint.x - touchLocation.x); //Slow down increment 344 | CGFloat hChange = (touchLocation.y - prevPoint.y); //Slow down increment 345 | 346 | CGAffineTransform t = self.transform; 347 | [self setTransform:CGAffineTransformIdentity]; 348 | 349 | CGRect scaleRect = CGRectMake(self.frame.origin.x, self.frame.origin.y,MAX(self.frame.size.width + (wChange*2), 1+_globalInset*2), MAX(self.frame.size.height + (hChange*2), 1+_globalInset*2)); 350 | 351 | scaleRect = CGRectSetCenter(scaleRect, self.center); 352 | [self setFrame:scaleRect]; 353 | 354 | [self setTransform:t]; 355 | 356 | if([_delegate respondsToSelector:@selector(stickerViewDidChangeEditing:)]) 357 | [_delegate stickerViewDidChangeEditing:self]; 358 | } 359 | else if ([recognizer state] == UIGestureRecognizerStateEnded) 360 | { 361 | if([_delegate respondsToSelector:@selector(stickerViewDidEndEditing:)]) 362 | [_delegate stickerViewDidEndEditing:self]; 363 | } 364 | 365 | prevPoint = touchLocation; 366 | } 367 | 368 | -(void)rotateViewPanGesture:(UIPanGestureRecognizer *)recognizer 369 | { 370 | touchLocation = [recognizer locationInView:self.superview]; 371 | 372 | CGPoint center = CGRectGetCenter(self.frame); 373 | 374 | if ([recognizer state] == UIGestureRecognizerStateBegan) 375 | { 376 | deltaAngle = atan2(touchLocation.y-center.y, touchLocation.x-center.x)-CGAffineTransformGetAngle(self.transform); 377 | 378 | initialBounds = self.bounds; 379 | initialDistance = CGPointGetDistance(center, touchLocation); 380 | 381 | if([_delegate respondsToSelector:@selector(stickerViewDidBeginEditing:)]) 382 | [_delegate stickerViewDidBeginEditing:self]; 383 | } 384 | else if ([recognizer state] == UIGestureRecognizerStateChanged) 385 | { 386 | float ang = atan2(touchLocation.y-center.y, touchLocation.x-center.x); 387 | 388 | float angleDiff = deltaAngle - ang; 389 | // float angleDiff = -ang; 390 | [self setTransform:CGAffineTransformMakeRotation(-angleDiff)]; 391 | [self setNeedsDisplay]; 392 | 393 | //Finding scale between current touchPoint and previous touchPoint 394 | double scale = sqrtf(CGPointGetDistance(center, touchLocation)/initialDistance); 395 | 396 | CGRect scaleRect = CGRectScale(initialBounds, scale, scale); 397 | 398 | if (scaleRect.size.width >= (1+_globalInset*2) && scaleRect.size.height >= (1+_globalInset*2)) 399 | { 400 | [self setBounds:scaleRect]; 401 | } 402 | 403 | if([_delegate respondsToSelector:@selector(stickerViewDidChangeEditing:)]) 404 | [_delegate stickerViewDidChangeEditing:self]; 405 | } 406 | else if ([recognizer state] == UIGestureRecognizerStateEnded) 407 | { 408 | if([_delegate respondsToSelector:@selector(stickerViewDidEndEditing:)]) 409 | [_delegate stickerViewDidEndEditing:self]; 410 | } 411 | } 412 | 413 | 414 | 415 | 416 | @end 417 | -------------------------------------------------------------------------------- /IQStickerView/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackiftekhar/IQStickerView/689457dcf95c1cef29fa07bff92e618251ee937f/IQStickerView/close.png -------------------------------------------------------------------------------- /IQStickerView/resize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackiftekhar/IQStickerView/689457dcf95c1cef29fa07bff92e618251ee937f/IQStickerView/resize.png -------------------------------------------------------------------------------- /IQStickerView/rotate_scale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackiftekhar/IQStickerView/689457dcf95c1cef29fa07bff92e618251ee937f/IQStickerView/rotate_scale.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Mohd Iftekhar Qurashi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | IQStickerView 2 | ============= 3 | 4 | IQStickerView with OneFingerRotation, Scale, Resize and Close feature. 5 | 6 | Features:- 7 | 1) One Finger Rotation Scale. 8 | 2) One Finger Resize. 9 | 3) Enable/Desable Rotation, Scale, Resize with properties. 10 | 4) Auto manage Multiple IQStickerView. 11 | 5) Can work with UIScrollView also. 12 | 6) Fast Responsiveness. 13 | 14 | 15 | LICENSE 16 | --- 17 | Distributed under the MIT License. 18 | 19 | Contributions 20 | --- 21 | Any contribution is more than welcome! You can contribute through pull requests and issues on GitHub. 22 | 23 | Author 24 | --- 25 | If you wish to contact me, email at: hack.iftekhar@gmail.com 26 | 27 | 28 | 29 | ### Reference 30 | Inspired by [TDResizerView](https://github.com/Thavasidurai/TDResizerView). 31 | [ZDStickerView](https://github.com/zedoul/ZDStickerView) is also added a reference to [TDResizerView](https://github.com/Thavasidurai/TDResizerView). 32 | -------------------------------------------------------------------------------- /StickerView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | AF83919617C350EA003CFD67 /* close.png in Resources */ = {isa = PBXBuildFile; fileRef = AF83919317C350EA003CFD67 /* close.png */; }; 11 | AF83919717C350EA003CFD67 /* resize.png in Resources */ = {isa = PBXBuildFile; fileRef = AF83919417C350EA003CFD67 /* resize.png */; }; 12 | AF83919817C350EA003CFD67 /* rotate_scale.png in Resources */ = {isa = PBXBuildFile; fileRef = AF83919517C350EA003CFD67 /* rotate_scale.png */; }; 13 | AF93E19D17C21AE0000EFDA2 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF93E19C17C21ADF000EFDA2 /* UIKit.framework */; }; 14 | AF93E19F17C21AE0000EFDA2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF93E19E17C21AE0000EFDA2 /* Foundation.framework */; }; 15 | AF93E1A117C21AE0000EFDA2 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF93E1A017C21AE0000EFDA2 /* CoreGraphics.framework */; }; 16 | AF93E1A717C21AE0000EFDA2 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = AF93E1A517C21AE0000EFDA2 /* InfoPlist.strings */; }; 17 | AF93E1A917C21AE0000EFDA2 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = AF93E1A817C21AE0000EFDA2 /* main.m */; }; 18 | AF93E1AD17C21AE0000EFDA2 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AF93E1AC17C21AE0000EFDA2 /* AppDelegate.m */; }; 19 | AF93E1AF17C21AE0000EFDA2 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = AF93E1AE17C21AE0000EFDA2 /* Default.png */; }; 20 | AF93E1B117C21AE0000EFDA2 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AF93E1B017C21AE0000EFDA2 /* Default@2x.png */; }; 21 | AF93E1B317C21AE0000EFDA2 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AF93E1B217C21AE0000EFDA2 /* Default-568h@2x.png */; }; 22 | AF93E1B617C21AE0000EFDA2 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AF93E1B517C21AE0000EFDA2 /* ViewController.m */; }; 23 | AF93E1B917C21AE0000EFDA2 /* ViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = AF93E1B717C21AE0000EFDA2 /* ViewController.xib */; }; 24 | AF93E1C817C21C33000EFDA2 /* IQStickerView.m in Sources */ = {isa = PBXBuildFile; fileRef = AF93E1C417C21C33000EFDA2 /* IQStickerView.m */; }; 25 | AF93E1CA17C21E4B000EFDA2 /* sample1.jpeg in Resources */ = {isa = PBXBuildFile; fileRef = AF93E1C917C21E4B000EFDA2 /* sample1.jpeg */; }; 26 | AF93E1CC17C22649000EFDA2 /* sample2.jpeg in Resources */ = {isa = PBXBuildFile; fileRef = AF93E1CB17C22649000EFDA2 /* sample2.jpeg */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXFileReference section */ 30 | AF83919317C350EA003CFD67 /* close.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = close.png; sourceTree = ""; }; 31 | AF83919417C350EA003CFD67 /* resize.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = resize.png; sourceTree = ""; }; 32 | AF83919517C350EA003CFD67 /* rotate_scale.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = rotate_scale.png; sourceTree = ""; }; 33 | AF93E19917C21ADF000EFDA2 /* StickerView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = StickerView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | AF93E19C17C21ADF000EFDA2 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 35 | AF93E19E17C21AE0000EFDA2 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 36 | AF93E1A017C21AE0000EFDA2 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 37 | AF93E1A417C21AE0000EFDA2 /* StickerView-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "StickerView-Info.plist"; sourceTree = ""; }; 38 | AF93E1A617C21AE0000EFDA2 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 39 | AF93E1A817C21AE0000EFDA2 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 40 | AF93E1AA17C21AE0000EFDA2 /* StickerView-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "StickerView-Prefix.pch"; sourceTree = ""; }; 41 | AF93E1AB17C21AE0000EFDA2 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 42 | AF93E1AC17C21AE0000EFDA2 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 43 | AF93E1AE17C21AE0000EFDA2 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 44 | AF93E1B017C21AE0000EFDA2 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 45 | AF93E1B217C21AE0000EFDA2 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 46 | AF93E1B417C21AE0000EFDA2 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 47 | AF93E1B517C21AE0000EFDA2 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 48 | AF93E1B817C21AE0000EFDA2 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController.xib; sourceTree = ""; }; 49 | AF93E1C317C21C33000EFDA2 /* IQStickerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IQStickerView.h; sourceTree = ""; }; 50 | AF93E1C417C21C33000EFDA2 /* IQStickerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IQStickerView.m; sourceTree = ""; }; 51 | AF93E1C917C21E4B000EFDA2 /* sample1.jpeg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = sample1.jpeg; sourceTree = ""; }; 52 | AF93E1CB17C22649000EFDA2 /* sample2.jpeg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = sample2.jpeg; sourceTree = ""; }; 53 | /* End PBXFileReference section */ 54 | 55 | /* Begin PBXFrameworksBuildPhase section */ 56 | AF93E19617C21ADF000EFDA2 /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | AF93E19D17C21AE0000EFDA2 /* UIKit.framework in Frameworks */, 61 | AF93E19F17C21AE0000EFDA2 /* Foundation.framework in Frameworks */, 62 | AF93E1A117C21AE0000EFDA2 /* CoreGraphics.framework in Frameworks */, 63 | ); 64 | runOnlyForDeploymentPostprocessing = 0; 65 | }; 66 | /* End PBXFrameworksBuildPhase section */ 67 | 68 | /* Begin PBXGroup section */ 69 | AF93E19017C21ADF000EFDA2 = { 70 | isa = PBXGroup; 71 | children = ( 72 | AF93E1C917C21E4B000EFDA2 /* sample1.jpeg */, 73 | AF93E1CB17C22649000EFDA2 /* sample2.jpeg */, 74 | AF93E1BF17C21C33000EFDA2 /* Classes */, 75 | AF93E1A217C21AE0000EFDA2 /* StickerView */, 76 | AF93E19B17C21ADF000EFDA2 /* Frameworks */, 77 | AF93E19A17C21ADF000EFDA2 /* Products */, 78 | ); 79 | sourceTree = ""; 80 | }; 81 | AF93E19A17C21ADF000EFDA2 /* Products */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | AF93E19917C21ADF000EFDA2 /* StickerView.app */, 85 | ); 86 | name = Products; 87 | sourceTree = ""; 88 | }; 89 | AF93E19B17C21ADF000EFDA2 /* Frameworks */ = { 90 | isa = PBXGroup; 91 | children = ( 92 | AF93E19C17C21ADF000EFDA2 /* UIKit.framework */, 93 | AF93E19E17C21AE0000EFDA2 /* Foundation.framework */, 94 | AF93E1A017C21AE0000EFDA2 /* CoreGraphics.framework */, 95 | ); 96 | name = Frameworks; 97 | sourceTree = ""; 98 | }; 99 | AF93E1A217C21AE0000EFDA2 /* StickerView */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | AF93E1AB17C21AE0000EFDA2 /* AppDelegate.h */, 103 | AF93E1AC17C21AE0000EFDA2 /* AppDelegate.m */, 104 | AF93E1B417C21AE0000EFDA2 /* ViewController.h */, 105 | AF93E1B517C21AE0000EFDA2 /* ViewController.m */, 106 | AF93E1B717C21AE0000EFDA2 /* ViewController.xib */, 107 | AF93E1A317C21AE0000EFDA2 /* Supporting Files */, 108 | ); 109 | path = StickerView; 110 | sourceTree = ""; 111 | }; 112 | AF93E1A317C21AE0000EFDA2 /* Supporting Files */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | AF93E1A417C21AE0000EFDA2 /* StickerView-Info.plist */, 116 | AF93E1A517C21AE0000EFDA2 /* InfoPlist.strings */, 117 | AF93E1A817C21AE0000EFDA2 /* main.m */, 118 | AF93E1AA17C21AE0000EFDA2 /* StickerView-Prefix.pch */, 119 | AF93E1AE17C21AE0000EFDA2 /* Default.png */, 120 | AF93E1B017C21AE0000EFDA2 /* Default@2x.png */, 121 | AF93E1B217C21AE0000EFDA2 /* Default-568h@2x.png */, 122 | ); 123 | name = "Supporting Files"; 124 | sourceTree = ""; 125 | }; 126 | AF93E1BF17C21C33000EFDA2 /* Classes */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | AF83919317C350EA003CFD67 /* close.png */, 130 | AF83919417C350EA003CFD67 /* resize.png */, 131 | AF83919517C350EA003CFD67 /* rotate_scale.png */, 132 | AF93E1C317C21C33000EFDA2 /* IQStickerView.h */, 133 | AF93E1C417C21C33000EFDA2 /* IQStickerView.m */, 134 | ); 135 | name = Classes; 136 | path = IQStickerView; 137 | sourceTree = ""; 138 | }; 139 | /* End PBXGroup section */ 140 | 141 | /* Begin PBXNativeTarget section */ 142 | AF93E19817C21ADF000EFDA2 /* StickerView */ = { 143 | isa = PBXNativeTarget; 144 | buildConfigurationList = AF93E1BC17C21AE0000EFDA2 /* Build configuration list for PBXNativeTarget "StickerView" */; 145 | buildPhases = ( 146 | AF93E19517C21ADF000EFDA2 /* Sources */, 147 | AF93E19617C21ADF000EFDA2 /* Frameworks */, 148 | AF93E19717C21ADF000EFDA2 /* Resources */, 149 | ); 150 | buildRules = ( 151 | ); 152 | dependencies = ( 153 | ); 154 | name = StickerView; 155 | productName = StickerView; 156 | productReference = AF93E19917C21ADF000EFDA2 /* StickerView.app */; 157 | productType = "com.apple.product-type.application"; 158 | }; 159 | /* End PBXNativeTarget section */ 160 | 161 | /* Begin PBXProject section */ 162 | AF93E19117C21ADF000EFDA2 /* Project object */ = { 163 | isa = PBXProject; 164 | attributes = { 165 | LastUpgradeCheck = 0460; 166 | ORGANIZATIONNAME = Iftekhar; 167 | }; 168 | buildConfigurationList = AF93E19417C21ADF000EFDA2 /* Build configuration list for PBXProject "StickerView" */; 169 | compatibilityVersion = "Xcode 3.2"; 170 | developmentRegion = English; 171 | hasScannedForEncodings = 0; 172 | knownRegions = ( 173 | en, 174 | ); 175 | mainGroup = AF93E19017C21ADF000EFDA2; 176 | productRefGroup = AF93E19A17C21ADF000EFDA2 /* Products */; 177 | projectDirPath = ""; 178 | projectRoot = ""; 179 | targets = ( 180 | AF93E19817C21ADF000EFDA2 /* StickerView */, 181 | ); 182 | }; 183 | /* End PBXProject section */ 184 | 185 | /* Begin PBXResourcesBuildPhase section */ 186 | AF93E19717C21ADF000EFDA2 /* Resources */ = { 187 | isa = PBXResourcesBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | AF93E1A717C21AE0000EFDA2 /* InfoPlist.strings in Resources */, 191 | AF93E1AF17C21AE0000EFDA2 /* Default.png in Resources */, 192 | AF93E1B117C21AE0000EFDA2 /* Default@2x.png in Resources */, 193 | AF93E1B317C21AE0000EFDA2 /* Default-568h@2x.png in Resources */, 194 | AF93E1B917C21AE0000EFDA2 /* ViewController.xib in Resources */, 195 | AF93E1CA17C21E4B000EFDA2 /* sample1.jpeg in Resources */, 196 | AF93E1CC17C22649000EFDA2 /* sample2.jpeg in Resources */, 197 | AF83919617C350EA003CFD67 /* close.png in Resources */, 198 | AF83919717C350EA003CFD67 /* resize.png in Resources */, 199 | AF83919817C350EA003CFD67 /* rotate_scale.png in Resources */, 200 | ); 201 | runOnlyForDeploymentPostprocessing = 0; 202 | }; 203 | /* End PBXResourcesBuildPhase section */ 204 | 205 | /* Begin PBXSourcesBuildPhase section */ 206 | AF93E19517C21ADF000EFDA2 /* Sources */ = { 207 | isa = PBXSourcesBuildPhase; 208 | buildActionMask = 2147483647; 209 | files = ( 210 | AF93E1A917C21AE0000EFDA2 /* main.m in Sources */, 211 | AF93E1AD17C21AE0000EFDA2 /* AppDelegate.m in Sources */, 212 | AF93E1B617C21AE0000EFDA2 /* ViewController.m in Sources */, 213 | AF93E1C817C21C33000EFDA2 /* IQStickerView.m in Sources */, 214 | ); 215 | runOnlyForDeploymentPostprocessing = 0; 216 | }; 217 | /* End PBXSourcesBuildPhase section */ 218 | 219 | /* Begin PBXVariantGroup section */ 220 | AF93E1A517C21AE0000EFDA2 /* InfoPlist.strings */ = { 221 | isa = PBXVariantGroup; 222 | children = ( 223 | AF93E1A617C21AE0000EFDA2 /* en */, 224 | ); 225 | name = InfoPlist.strings; 226 | sourceTree = ""; 227 | }; 228 | AF93E1B717C21AE0000EFDA2 /* ViewController.xib */ = { 229 | isa = PBXVariantGroup; 230 | children = ( 231 | AF93E1B817C21AE0000EFDA2 /* en */, 232 | ); 233 | name = ViewController.xib; 234 | sourceTree = ""; 235 | }; 236 | /* End PBXVariantGroup section */ 237 | 238 | /* Begin XCBuildConfiguration section */ 239 | AF93E1BA17C21AE0000EFDA2 /* Debug */ = { 240 | isa = XCBuildConfiguration; 241 | buildSettings = { 242 | ALWAYS_SEARCH_USER_PATHS = NO; 243 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 244 | CLANG_CXX_LIBRARY = "libc++"; 245 | CLANG_ENABLE_OBJC_ARC = YES; 246 | CLANG_WARN_CONSTANT_CONVERSION = YES; 247 | CLANG_WARN_EMPTY_BODY = YES; 248 | CLANG_WARN_ENUM_CONVERSION = YES; 249 | CLANG_WARN_INT_CONVERSION = YES; 250 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 251 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 252 | COPY_PHASE_STRIP = NO; 253 | GCC_C_LANGUAGE_STANDARD = gnu99; 254 | GCC_DYNAMIC_NO_PIC = NO; 255 | GCC_OPTIMIZATION_LEVEL = 0; 256 | GCC_PREPROCESSOR_DEFINITIONS = ( 257 | "DEBUG=1", 258 | "$(inherited)", 259 | ); 260 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 261 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 262 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 263 | GCC_WARN_UNUSED_VARIABLE = YES; 264 | IPHONEOS_DEPLOYMENT_TARGET = 6.1; 265 | ONLY_ACTIVE_ARCH = YES; 266 | SDKROOT = iphoneos; 267 | }; 268 | name = Debug; 269 | }; 270 | AF93E1BB17C21AE0000EFDA2 /* Release */ = { 271 | isa = XCBuildConfiguration; 272 | buildSettings = { 273 | ALWAYS_SEARCH_USER_PATHS = NO; 274 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 275 | CLANG_CXX_LIBRARY = "libc++"; 276 | CLANG_ENABLE_OBJC_ARC = YES; 277 | CLANG_WARN_CONSTANT_CONVERSION = YES; 278 | CLANG_WARN_EMPTY_BODY = YES; 279 | CLANG_WARN_ENUM_CONVERSION = YES; 280 | CLANG_WARN_INT_CONVERSION = YES; 281 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 282 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 283 | COPY_PHASE_STRIP = YES; 284 | GCC_C_LANGUAGE_STANDARD = gnu99; 285 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 286 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 287 | GCC_WARN_UNUSED_VARIABLE = YES; 288 | IPHONEOS_DEPLOYMENT_TARGET = 6.1; 289 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 290 | SDKROOT = iphoneos; 291 | VALIDATE_PRODUCT = YES; 292 | }; 293 | name = Release; 294 | }; 295 | AF93E1BD17C21AE0000EFDA2 /* Debug */ = { 296 | isa = XCBuildConfiguration; 297 | buildSettings = { 298 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 299 | GCC_PREFIX_HEADER = "StickerView/StickerView-Prefix.pch"; 300 | INFOPLIST_FILE = "StickerView/StickerView-Info.plist"; 301 | IPHONEOS_DEPLOYMENT_TARGET = 4.3; 302 | PRODUCT_NAME = "$(TARGET_NAME)"; 303 | WRAPPER_EXTENSION = app; 304 | }; 305 | name = Debug; 306 | }; 307 | AF93E1BE17C21AE0000EFDA2 /* Release */ = { 308 | isa = XCBuildConfiguration; 309 | buildSettings = { 310 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 311 | GCC_PREFIX_HEADER = "StickerView/StickerView-Prefix.pch"; 312 | INFOPLIST_FILE = "StickerView/StickerView-Info.plist"; 313 | IPHONEOS_DEPLOYMENT_TARGET = 4.3; 314 | PRODUCT_NAME = "$(TARGET_NAME)"; 315 | WRAPPER_EXTENSION = app; 316 | }; 317 | name = Release; 318 | }; 319 | /* End XCBuildConfiguration section */ 320 | 321 | /* Begin XCConfigurationList section */ 322 | AF93E19417C21ADF000EFDA2 /* Build configuration list for PBXProject "StickerView" */ = { 323 | isa = XCConfigurationList; 324 | buildConfigurations = ( 325 | AF93E1BA17C21AE0000EFDA2 /* Debug */, 326 | AF93E1BB17C21AE0000EFDA2 /* Release */, 327 | ); 328 | defaultConfigurationIsVisible = 0; 329 | defaultConfigurationName = Release; 330 | }; 331 | AF93E1BC17C21AE0000EFDA2 /* Build configuration list for PBXNativeTarget "StickerView" */ = { 332 | isa = XCConfigurationList; 333 | buildConfigurations = ( 334 | AF93E1BD17C21AE0000EFDA2 /* Debug */, 335 | AF93E1BE17C21AE0000EFDA2 /* Release */, 336 | ); 337 | defaultConfigurationIsVisible = 0; 338 | defaultConfigurationName = Release; 339 | }; 340 | /* End XCConfigurationList section */ 341 | }; 342 | rootObject = AF93E19117C21ADF000EFDA2 /* Project object */; 343 | } 344 | -------------------------------------------------------------------------------- /StickerView/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // Created by Iftekhar Mac Pro on 15/8/13. 4 | 5 | #import 6 | 7 | @class ViewController; 8 | 9 | @interface AppDelegate : UIResponder 10 | 11 | @property (strong, nonatomic) UIWindow *window; 12 | 13 | @property (strong, nonatomic) ViewController *viewController; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /StickerView/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // Created by Iftekhar Mac Pro on 8/19/13. 4 | 5 | #import "AppDelegate.h" 6 | 7 | #import "ViewController.h" 8 | 9 | @implementation AppDelegate 10 | @synthesize window = _window; 11 | @synthesize viewController = _viewController; 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 16 | // Override point for customization after application launch. 17 | self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil]; 18 | self.window.rootViewController = self.viewController; 19 | [self.window makeKeyAndVisible]; 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application 24 | { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 27 | } 28 | 29 | - (void)applicationDidEnterBackground:(UIApplication *)application 30 | { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | - (void)applicationWillEnterForeground:(UIApplication *)application 36 | { 37 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | - (void)applicationDidBecomeActive:(UIApplication *)application 41 | { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | - (void)applicationWillTerminate:(UIApplication *)application 46 | { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /StickerView/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackiftekhar/IQStickerView/689457dcf95c1cef29fa07bff92e618251ee937f/StickerView/Default-568h@2x.png -------------------------------------------------------------------------------- /StickerView/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackiftekhar/IQStickerView/689457dcf95c1cef29fa07bff92e618251ee937f/StickerView/Default.png -------------------------------------------------------------------------------- /StickerView/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackiftekhar/IQStickerView/689457dcf95c1cef29fa07bff92e618251ee937f/StickerView/Default@2x.png -------------------------------------------------------------------------------- /StickerView/StickerView-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.iftekhar.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /StickerView/StickerView-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'StickerView' target in the 'StickerView' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /StickerView/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // StickerView 4 | // 5 | // Created by Iftekhar Mac Pro on 8/19/13. 6 | // Copyright (c) 2013 Iftekhar. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | { 13 | UIView *anView; 14 | IBOutlet UIScrollView *scrollViewSample; 15 | } 16 | @end 17 | -------------------------------------------------------------------------------- /StickerView/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // Created by Iftekhar Mac Pro on 15/8/13. 4 | 5 | #import "ViewController.h" 6 | #import "IQStickerView.h" 7 | 8 | @interface ViewController () 9 | 10 | @end 11 | 12 | @implementation ViewController 13 | 14 | - (void)viewDidLoad 15 | { 16 | [super viewDidLoad]; 17 | 18 | /**/ 19 | IQStickerView *stickerView = [[IQStickerView alloc] initWithFrame:CGRectMake(10, 10, 100, 100)]; 20 | UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"sample1.jpeg"]]; 21 | [imageView setContentMode:UIViewContentModeScaleAspectFit]; 22 | [stickerView setContentView:imageView]; 23 | [self.view addSubview:stickerView]; 24 | /**/ 25 | 26 | 27 | 28 | /**/ 29 | UIView *aView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)]; 30 | [aView setBackgroundColor:[UIColor greenColor]]; 31 | [aView setClipsToBounds:YES]; 32 | 33 | UILabel *aLabel = [[UILabel alloc] initWithFrame:CGRectMake(30, 20, 120, 20)]; 34 | [aLabel setAutoresizingMask:(UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin)]; 35 | [aLabel setText:@"Sample Text"]; 36 | [aView addSubview:aLabel]; 37 | 38 | UIButton *aButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 39 | [aButton setAutoresizingMask:(UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin)]; 40 | [aButton setTitle:@"Sample Button" forState:UIControlStateNormal]; 41 | [aButton setFrame:CGRectMake(30, 140, 120, 30)]; 42 | [aView addSubview:aButton]; 43 | 44 | UIScrollView *scrollview = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 160, 200, 40)]; 45 | [scrollview setAutoresizingMask:(UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleHeight)]; 46 | [scrollview setBackgroundColor:[UIColor greenColor]]; 47 | [scrollview setContentSize:CGSizeMake(200, 200)]; 48 | [aView addSubview:scrollview]; 49 | 50 | IQStickerView *stickerView1 = [[IQStickerView alloc] initWithFrame:CGRectMake(120, 10, 180, 180)]; 51 | [stickerView1 setContentView:aView]; 52 | [self.view addSubview:stickerView1]; 53 | /**/ 54 | 55 | /**/ 56 | anView = [[UIView alloc] initWithFrame:scrollViewSample.bounds]; 57 | [aView setUserInteractionEnabled:YES]; 58 | [anView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight)]; 59 | [scrollViewSample addSubview:anView]; 60 | 61 | IQStickerView *stickerView2 = [[IQStickerView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; 62 | [stickerView2 setCenter:anView.center]; 63 | UIImageView *imageView2 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"sample2.jpeg"]]; 64 | [imageView2 setContentMode:UIViewContentModeScaleAspectFit]; 65 | [stickerView2 setContentView:imageView2]; 66 | [anView addSubview:stickerView2]; 67 | /**/ 68 | 69 | // Do any additional setup after loading the view, typically from a nib. 70 | } 71 | 72 | -(void)scrollViewDidZoom:(UIScrollView *)scrollView 73 | { 74 | //Control size maintenance. 75 | for (IQStickerView *sticker in anView.subviews) 76 | if ([sticker isKindOfClass:[IQStickerView class]]) 77 | [sticker refresh]; 78 | } 79 | 80 | - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView 81 | { 82 | return anView; 83 | } 84 | 85 | - (void)didReceiveMemoryWarning 86 | { 87 | [super didReceiveMemoryWarning]; 88 | // Dispose of any resources that can be recreated. 89 | } 90 | 91 | - (void)viewDidUnload { 92 | scrollViewSample = nil; 93 | [super viewDidUnload]; 94 | } 95 | 96 | 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /StickerView/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /StickerView/en.lproj/ViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1552 5 | 12C54 6 | 3084 7 | 1187.34 8 | 625.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 2083 12 | 13 | 14 | IBProxyObject 15 | IBUIScrollView 16 | IBUIView 17 | 18 | 19 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 20 | 21 | 22 | PluginDependencyRecalculationVersion 23 | 24 | 25 | 26 | 27 | IBFilesOwner 28 | IBCocoaTouchFramework 29 | 30 | 31 | IBFirstResponder 32 | IBCocoaTouchFramework 33 | 34 | 35 | 36 | 274 37 | 38 | 39 | 40 | 282 41 | {{0, 204}, {320, 256}} 42 | 43 | 44 | 45 | _NS:9 46 | 47 | 2 48 | MC45Njg2Mjc1MTI1IDAuNzE3NjQ3MDc1NyAwLjMzNzI1NDkxMTcAA 49 | 50 | YES 51 | YES 52 | IBCocoaTouchFramework 53 | 10 54 | 55 | 56 | {{0, 20}, {320, 460}} 57 | 58 | 59 | 60 | 61 | 1 62 | MC45Nzk1OTE4MzY3IDAuMjg3MTg0MTk4NiAwLjM0MDM5MTY3ODcAA 63 | 64 | NO 65 | 66 | 67 | IBUIScreenMetrics 68 | 69 | YES 70 | 71 | 72 | 73 | 74 | 75 | {320, 480} 76 | {480, 320} 77 | 78 | 79 | IBCocoaTouchFramework 80 | Retina 3.5 Full Screen 81 | 0 82 | 83 | IBCocoaTouchFramework 84 | 85 | 86 | 87 | 88 | 89 | 90 | view 91 | 92 | 93 | 94 | 7 95 | 96 | 97 | 98 | scrollViewSample 99 | 100 | 101 | 102 | 9 103 | 104 | 105 | 106 | delegate 107 | 108 | 109 | 110 | 10 111 | 112 | 113 | 114 | 115 | 116 | 0 117 | 118 | 119 | 120 | 121 | 122 | -1 123 | 124 | 125 | File's Owner 126 | 127 | 128 | -2 129 | 130 | 131 | 132 | 133 | 6 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 8 142 | 143 | 144 | 145 | 146 | 147 | 148 | ViewController 149 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 150 | UIResponder 151 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 152 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 153 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 154 | 155 | 156 | 157 | 158 | 159 | 10 160 | 161 | 162 | 163 | 164 | ViewController 165 | UIViewController 166 | 167 | scrollViewSample 168 | UIScrollView 169 | 170 | 171 | scrollViewSample 172 | 173 | scrollViewSample 174 | UIScrollView 175 | 176 | 177 | 178 | IBProjectSource 179 | ./Classes/ViewController.h 180 | 181 | 182 | 183 | 184 | 0 185 | IBCocoaTouchFramework 186 | YES 187 | 3 188 | 2083 189 | 190 | 191 | -------------------------------------------------------------------------------- /StickerView/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // StickerView 4 | // 5 | // Created by Iftekhar Mac Pro on 8/19/13. 6 | // Copyright (c) 2013 Iftekhar. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /sample1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackiftekhar/IQStickerView/689457dcf95c1cef29fa07bff92e618251ee937f/sample1.jpeg -------------------------------------------------------------------------------- /sample2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackiftekhar/IQStickerView/689457dcf95c1cef29fa07bff92e618251ee937f/sample2.jpeg --------------------------------------------------------------------------------