SlideShare a Scribd company logo
iPhone SDK




http://kishikawakatsumi.com

Twitter
@k_katsumi

24/7 twenty-four seven
http://d.hatena.ne.jp/KishikawaKatsumi/
iPhone SDK




http://kishikawakatsumi.com

Twitter
@k_katsumi

24/7 twenty-four seven
http://d.hatena.ne.jp/KishikawaKatsumi/
iPhone SDK


•     touch   •      on the WEB

•LDR touch    •
•             •i-Radio
•LCD Clock    •
•Subway Map   •
•MyWebClip
•             •
iPhone SDK

http://github.com/kishikawakatsumi

•hatena-touch     •DescriptionBuilder
•ldr-touch        •TiledLayerView
•tv-listings      •UICCalendarPicker
•MapKit-Route-Directions
•FlipCardNavigationView
•PhotoFlipCardView
iPhone SDK

http://github.com/kishikawakatsumi

•UICKeyChainStore
•TiKeyChainStore
•CropImageSample
iPhone SDK
iPhone SDK
iPhone SDK
iPhone SDK
iPhone SDK
iPhone SDK
#import <UIKit/UIKit.h>

extern NSString * const FFNavigationBarSwipedNotification;

@interface FFNavigationBar : UINavigationBar

@end
#import "FFNavigationBar.h"

@implementation FFNavigationBar
          iPhone SDK
- (void)initCommon {
    self.barStyle = UIBarStyleBlack;
}

- (id)init {
    self = [super init];
    if (self) {
        [self initCommon];
    }
    return self;
}

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self initCommon];
    }
    return self;
}
- (id)initWithCoder:(NSCoder *)coder {
    self = [super initWithCoder:coder];

        iPhone SDK
    if (self) {
        [self initCommon];
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    [background drawAsPatternInRect:rect];
}

@end
iPhone SDK
iPhone SDK



UITableView
iPhone SDK



UITableViewCell
iPhone SDK
iPhone SDK

iPhone
iPhone SDK
iPhone SDK
iPhone SDK



•UIImageView
•CALayer
•[UIImage drawRect:]
iPhone SDK



•UIImageView
•CALayer
•[UIImage drawRect:]
iPhone SDK
UIImageView
UIImageView
CALayer
UIImage   draw~




                  UIButton
iPhone SDK
UIImage   draw~
PNG
http://sonson.jp/?p=745

                  PNG
=>        UI
=>


=>JPEG
iPhone SDK
CALayer *backgroundImageLayer = [CALayer layer];
backgroundImageLayer.frame =
CGRectMake(17.0f, 12.0f, 285.0f, 310.0f);
backgroundImageLayer.contents = (id)[[UIImage
imageNamed:@"photo_bg.png"] CGImage];
[self.contentView.layer addSublayer:backgroundImageLayer];

photoImageView = [[UIImageView alloc]
initWithFrame:CGRectMake(30.0f, 18.0f, 260.0f, 260.0f)];
photoImageView.backgroundColor = [UIColor clearColor];
[self.contentView addSubview:photoImageView];
[photoImageView release];
iPhone SDK
preloaderBackground =
[[UIImageView alloc]
initWithFrame:CGRectMake(95.0f, 95.0f, 70.0f, 70.0f)];
preloaderBackground.backgroundColor = [UIColor
clearColor];
preloaderBackground.image = [UIImage
imageNamed:@"photo_preloader.png"];
[photoImageView addSubview:preloaderBackground];
[preloaderBackground release];

preloader =
[[FFPreloaderView alloc]
initWithFrame:CGRectMake(5.0f, 1.0f, 60.0f, 20.0f)];
[preloaderBackground addSubview:preloader];
[preloader release];
iPhone SDK
CALayer *shadowLayer = [CALayer layer];
shadowLayer.frame =
CGRectMake(30.0f, 18.0f, 260.0f, 260.0f);
shadowLayer.contents = (id)[[UIImage
imageNamed:@"photo_shadow.png"] CGImage];
[cellContentView.layer addSublayer:shadowLayer];

favoriteButton = [[FFFavoriteButton alloc]
initWithFrame:CGRectMake(19.0f, 24.0f, 75.0f, 29.0f)];
favoriteButton.exclusiveTouch = YES;
iPhone SDK
iPhone SDK



     NSCache


        NSDictionary
@interface FFImageCache : NSObject {
    NSFileManager *fileManager;

           iPhone SDK
    NSString *cacheDirectory;

    NSCache *cache;
}

+ (FFImageCache *)sharedInstance;
- (UIImage *)cachedImageWithURL:(NSString *)URL;
- (UIImage *)cachedImageWithURL:(NSString *)URL
                   defaultImage:(UIImage *)defaultImage;
- (UIImage *)cachedImageWithURL:(NSString *)URL
                           size:(NSInteger)size;
- (UIImage *)cachedImageWithURL:(NSString *)URL
                           size:(NSInteger)size
                   defaultImage:(UIImage *)defaultImage;
- (void)storeImage:(UIImage *)image data:(NSData *)data
               URL:(NSString *)URL;
- (void)purgeMemoryCache;

- (void)deleteAllCacheFiles;

@end
iPhone SDK




=>
- (UIImage *)cachedImageWithURL:(NSString *)URL
                   defaultImage:(UIImage *)defaultImage {

           iPhone SDK
    NSString *key = [FFImageCache keyForURL:URL];
    UIImage *cachedImage = [cache objectForKey:key];
    if (cachedImage) {
        return cachedImage;
    }

    cachedImage = [UIImage imageWithContentsOfFile:[self pathForKey:key]];
    if (cachedImage) {
        [cache setObject:cachedImage forKey:key];
    }

    return cachedImage;
}

- (void)storeImage:(UIImage *)image data:(NSData *)data URL:(NSString *)URL
{
    NSString *key = [FFImageCache keyForURL:URL];
    [cache setObject:image forKey:key];

    [data writeToFile:[self pathForKey:key] atomically:NO];
}
+ (NSString *)keyForURL:(NSString *)URL {
! if ([URL length] == 0) {
! !
! }      iPhone SDK
       return nil;

! const char *cStr = [URL UTF8String];
! unsigned char result[16];
! CC_MD5(cStr, (CC_LONG)strlen(cStr), result);
! return [NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X
%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
            result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],result[8],
result[9], result[10], result[11],result[12], result[13],
result[14], result[15]]; !
}
iPhone SDK
iPhone SDK
- (void)scrollViewWillBeginDragging:(UIScrollView
*)scrollView {

         iPhone SDK
    if (!scrollView.isDecelerating) {
        contentOffsetY = scrollView.contentOffset.y;
    }
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView
willDecelerate:(BOOL)decelerate {
    shouldSnapScroll =
     scrollView.isTracking && scrollView.isDragging && !
     scrollView.isDecelerating;

    if (!decelerate) {
        [self loadImagesForOnscreenRows];
    }
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    [self loadImagesForOnscreenRows];

          iPhone SDK
   CGFloat distance =
    ABS(distance = contentOffsetY - scrollView.contentOffset.y);
   if (distance > timelineView.frame.size.height * 2) {
       shouldSnapScroll = YES;
   }
   if (!shouldSnapScroll) {
       return;
   }
   NSArray *indexPaths = timelineView.indexPathsForVisibleRows;
   if ([indexPaths count] == 0) {
       return;
   }

   if (contentOffsetY > scrollView.contentOffset.y) {
       scrollDirection = ScrollDirectionUp;
   }   else {
       scrollDirection = ScrollDirectionDown;
   }
CGFloat delta;
    NSIndexPath *indexPath;
    if (scrollDirection == ScrollDirectionUp) {


              iPhone SDK
        indexPath = [indexPaths objectAtIndex:0];
        CGRect rect = [timelineView rectForSection:indexPath.section];
        delta = scrollView.contentOffset.y - rect.origin.y;
        if (delta > 250.0f) {
             indexPath = [indexPaths lastObject];
             rect = [timelineView rectForSection:indexPath.section];
             delta = rect.origin.y - scrollView.contentOffset.y;
             if (delta < 0.0f) {
                 return;
             }
        }
    } else {
        indexPath = [indexPaths lastObject];
        CGRect rect = [timelineView rectForSection:indexPath.section];
        delta = rect.origin.y - scrollView.contentOffset.y;
        if (indexPath.section == [timelineManager count] - 1) {
             return;
        }
        if (delta < 0.0f) {
             return;
        }
        if (delta > 200.0f) {
             indexPath = [indexPaths objectAtIndex:0];
        }
    }
    if (scrollView.contentInset.top < 60.0f && scrollView.contentOffset.y > 0.0f) {
        NSIndexPath *toIndexPath = [NSIndexPath indexPathForRow:0
inSection:indexPath.section];
        [timelineView scrollToRowAtIndexPath:toIndexPath
atScrollPosition:UITableViewScrollPositionTop animated:YES];
    }
}
iPhone SDK
iPhone SDK
iPhone SDK
- (void)animateIcon:(BOOL)flag {
    [UIView transitionFromView:flag ? icon : selectedIcon

          iPhone SDK
                        toView:flag ? selectedIcon : icon duration:0.4

options:UIViewAnimationOptionTransitionFlipFromRight |

UIViewAnimationOptionShowHideTransitionViews completion:
     ^(BOOL finished) {
         if (!animaitionFinished) {
             [self animateIcon:!flag];
         }
     }];
}

- (void)setEnabled:(BOOL)enabled {
    [super setEnabled:enabled];
    if (enabled) {
        animaitionFinished = YES;
    } else {
        animaitionFinished = NO;
        shouldStartZoomAnimation = YES;
        [self animateIcon:self.selected];
    }
}
- (void)setSelected:(BOOL)selected {
    [super setSelected:selected];
    if (selected) {


              iPhone SDK
        icon.hidden = YES;
        selectedIcon.hidden = NO;
        animationIcon.image = [UIImage imageNamed:@"button_favorite_icon_selected.png"];
    } else {
        icon.hidden = NO;
        selectedIcon.hidden = YES;
        animationIcon.image = [UIImage imageNamed:@"button_favorite_icon.png"];
    }

    if (shouldStartZoomAnimation) {
        shouldStartZoomAnimation = NO;

        CABasicAnimation *zoom = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
        zoom.toValue = [NSNumber numberWithFloat:8.0f];

        CABasicAnimation *fade = [CABasicAnimation animationWithKeyPath:@"opacity"];
        fade.toValue = [NSNumber numberWithFloat:0.0f];

        CAAnimationGroup   *group = [CAAnimationGroup animation];
        group.delegate =   self;
        group.animations   = [NSArray arrayWithObjects:zoom, fade, nil];
        group.duration =   0.5;

        animationIcon.hidden = NO;
        [animationIcon.layer addAnimation:group forKey:nil];
    }
}

- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {
    animationIcon.hidden = YES;
}
iPhone SDK
iPhone SDK



UITableView
photoScrollView = [[UITableView alloc] initWithFrame:CGRectMake(6.0f,
30.0f, 50.0f, 264.0f)];


           iPhone SDK
photoScrollView.delegate = self;
photoScrollView.dataSource = self;
photoScrollView.rowHeight = 44.0f;
photoScrollView.separatorColor = [UIColor clearColor];
photoScrollView.pagingEnabled = YES;
photoScrollView.showsHorizontalScrollIndicator = NO;
photoScrollView.showsVerticalScrollIndicator = NO;
photoScrollView.backgroundColor = [UIColor clearColor];
photoScrollView.transform = CGAffineTransformMakeRotation(M_PI / -2.0f);
photoScrollView.center = CGPointMake(146.0f, 56.0f);
[cellContentView addSubview:photoScrollView];
[photoScrollView release];

pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(12.0f, 72.0f,
264.0f, 36.0f)];
pageControl.clipsToBounds = YES;
pageControl.hidesForSinglePage = YES;
pageControl.userInteractionEnabled = NO;
[cellContentView addSubview:pageControl];
[pageControl release];

UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(scrollViewTapped:)];
[photoScrollView addGestureRecognizer:tapRecognizer];
[tapRecognizer release];
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;

          iPhone SDK
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
(NSInteger)section {
    NSUInteger count = [photos count];
    if (count == 0) {
        pageControl.numberOfPages = 0;
    } else {
        pageControl.numberOfPages = MIN(count / 6 + 1, 17) ;
    }
    pageControl.currentPage = 0;
    return count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {

          iPhone SDK
    NSUInteger count = [photos count];
    NSUInteger numPages = count / 6 + 1;
    photoScrollView.contentSize = CGSizeMake(50.0f, 264.0f *
numPages);

    static NSString *cellIdentifier = @"Cell";
    FFMyPhotoImageCell *cell = (FFMyPhotoImageCell *)[tableView
dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        cell = [[[FFMyPhotoImageCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:cellIdentifier]autorelease];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
    }

    cell.URL = [[photos objectAtIndex:indexPath.row]
objectForKey:FFURLKey];

    return cell;
}
- (void)scrollViewDidScroll:(UIScrollView *)sender {
    if (pageControlUsed) {

          iPhone SDK
        return;
    }
    CGFloat pageWidth = photoScrollView.bounds.size.height;
    int page = floor((photoScrollView.contentOffset.y -
pageWidth / 2) / pageWidth) + 1;
! currentPage = MIN(page, 16);
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    pageControlUsed = NO;
    pageControl.currentPage = currentPage;
}

- (void)scrollViewTapped:(UIGestureRecognizer *)gestureRecognizer
{
    UITableView *tableView = (UITableView *)self.superview;
     [tableView.delegate tableView:tableView
didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:
0]];
}
iPhone SDK
CGFloat x = 41.0f;
CGSize size;



              iPhone SDK
NSString *username = user.username;
if ([username length] > 0) {
    UIFont *commentUsernameFont = [FFConstants commentUsernameFont];
    size = [username sizeWithFont:commentUsernameFont forWidth:253.0f - x
lineBreakMode:UILineBreakModeTailTruncation];
    [username drawInRect:CGRectMake(x, 6.0f, size.width, 12.0f) withFont:commentUsernameFont
lineBreakMode:UILineBreakModeTailTruncation alignment:UITextAlignmentLeft];
    x += size.width;

    NSString *action = NSLocalizedString(@" faved.", nil);
    UIFont *commentFont = [FFConstants commentFont];
    size = [action sizeWithFont:commentFont forWidth:253.0f - x
lineBreakMode:UILineBreakModeClip];
    [action drawInRect:CGRectMake(x, 6.0f, size.width, 12.0f) withFont:commentFont
lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentLeft];

    NSMutableString *str = [NSMutableString string];
    NSUInteger index = 0;
    NSUInteger length = [action length];;
    for (; index < length; index++) {
        [str appendString:[action substringWithRange:NSMakeRange(index, 1)]];
        CGSize sz = [str sizeWithFont:commentFont forWidth:253.0f - x
lineBreakMode:UILineBreakModeClip];
        if (sz.width >= size.width) {
            index++;
            break;
        }
    }

    action = [action substringWithRange:NSMakeRange(index, length - index)];
    [action drawInRect:CGRectMake(41.0f, 22.0f, 212.0f, 12.0f) withFont:commentFont
lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentLeft];
}
iPhone SDK

More Related Content

What's hot (20)

Adopting 3D Touch in your apps
Adopting 3D Touch in your appsAdopting 3D Touch in your apps
Adopting 3D Touch in your apps
Juan C Catalan
 
Your Second iPhone App - Code Listings
Your Second iPhone App - Code ListingsYour Second iPhone App - Code Listings
Your Second iPhone App - Code Listings
Vu Tran Lam
 
GHC Participant Training
GHC Participant TrainingGHC Participant Training
GHC Participant Training
AidIQ
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
Yekmer Simsek
 
Advancing the UI — Part 1: Look, Motion, and Gestures
Advancing the UI — Part 1: Look, Motion, and GesturesAdvancing the UI — Part 1: Look, Motion, and Gestures
Advancing the UI — Part 1: Look, Motion, and Gestures
Samsung Developers
 
Core Animation
Core AnimationCore Animation
Core Animation
bdudney
 
20180721 code defragment
20180721 code defragment20180721 code defragment
20180721 code defragment
Chiwon Song
 
The Ring programming language version 1.2 book - Part 35 of 84
The Ring programming language version 1.2 book - Part 35 of 84The Ring programming language version 1.2 book - Part 35 of 84
The Ring programming language version 1.2 book - Part 35 of 84
Mahmoud Samir Fayed
 
Matching Game In Java
Matching Game In JavaMatching Game In Java
Matching Game In Java
cmkandemir
 
@Ionic native/google-maps
@Ionic native/google-maps@Ionic native/google-maps
@Ionic native/google-maps
Masashi Katsumata
 
I os 04
I os 04I os 04
I os 04
信嘉 陳
 
Intro programacion funcional
Intro programacion funcionalIntro programacion funcional
Intro programacion funcional
NSCoder Mexico
 
303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code
jonmarimba
 
Slightly Advanced Android Wear ;)
Slightly Advanced Android Wear ;)Slightly Advanced Android Wear ;)
Slightly Advanced Android Wear ;)
Alfredo Morresi
 
20181020 advanced higher-order function
20181020 advanced higher-order function20181020 advanced higher-order function
20181020 advanced higher-order function
Chiwon Song
 
Android Sliding Menu dengan Navigation Drawer
Android Sliding Menu dengan Navigation DrawerAndroid Sliding Menu dengan Navigation Drawer
Android Sliding Menu dengan Navigation Drawer
Agus Haryanto
 
iOS Training Session-3
iOS Training Session-3iOS Training Session-3
iOS Training Session-3
Hussain Behestee
 
Developing for Plone using ArchGenXML / ArgoUML
Developing for Plone using ArchGenXML / ArgoUMLDeveloping for Plone using ArchGenXML / ArgoUML
Developing for Plone using ArchGenXML / ArgoUML
Jazkarta, Inc.
 
Letswift18 워크숍#1 스위프트 클린코드와 코드리뷰
Letswift18 워크숍#1 스위프트 클린코드와 코드리뷰Letswift18 워크숍#1 스위프트 클린코드와 코드리뷰
Letswift18 워크숍#1 스위프트 클린코드와 코드리뷰
Jung Kim
 
Intro to computer vision in .net update
Intro to computer vision in .net   updateIntro to computer vision in .net   update
Intro to computer vision in .net update
Stephen Lorello
 
Adopting 3D Touch in your apps
Adopting 3D Touch in your appsAdopting 3D Touch in your apps
Adopting 3D Touch in your apps
Juan C Catalan
 
Your Second iPhone App - Code Listings
Your Second iPhone App - Code ListingsYour Second iPhone App - Code Listings
Your Second iPhone App - Code Listings
Vu Tran Lam
 
GHC Participant Training
GHC Participant TrainingGHC Participant Training
GHC Participant Training
AidIQ
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
Yekmer Simsek
 
Advancing the UI — Part 1: Look, Motion, and Gestures
Advancing the UI — Part 1: Look, Motion, and GesturesAdvancing the UI — Part 1: Look, Motion, and Gestures
Advancing the UI — Part 1: Look, Motion, and Gestures
Samsung Developers
 
Core Animation
Core AnimationCore Animation
Core Animation
bdudney
 
20180721 code defragment
20180721 code defragment20180721 code defragment
20180721 code defragment
Chiwon Song
 
The Ring programming language version 1.2 book - Part 35 of 84
The Ring programming language version 1.2 book - Part 35 of 84The Ring programming language version 1.2 book - Part 35 of 84
The Ring programming language version 1.2 book - Part 35 of 84
Mahmoud Samir Fayed
 
Matching Game In Java
Matching Game In JavaMatching Game In Java
Matching Game In Java
cmkandemir
 
Intro programacion funcional
Intro programacion funcionalIntro programacion funcional
Intro programacion funcional
NSCoder Mexico
 
303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code
jonmarimba
 
Slightly Advanced Android Wear ;)
Slightly Advanced Android Wear ;)Slightly Advanced Android Wear ;)
Slightly Advanced Android Wear ;)
Alfredo Morresi
 
20181020 advanced higher-order function
20181020 advanced higher-order function20181020 advanced higher-order function
20181020 advanced higher-order function
Chiwon Song
 
Android Sliding Menu dengan Navigation Drawer
Android Sliding Menu dengan Navigation DrawerAndroid Sliding Menu dengan Navigation Drawer
Android Sliding Menu dengan Navigation Drawer
Agus Haryanto
 
Developing for Plone using ArchGenXML / ArgoUML
Developing for Plone using ArchGenXML / ArgoUMLDeveloping for Plone using ArchGenXML / ArgoUML
Developing for Plone using ArchGenXML / ArgoUML
Jazkarta, Inc.
 
Letswift18 워크숍#1 스위프트 클린코드와 코드리뷰
Letswift18 워크숍#1 스위프트 클린코드와 코드리뷰Letswift18 워크숍#1 스위프트 클린코드와 코드리뷰
Letswift18 워크숍#1 스위프트 클린코드와 코드리뷰
Jung Kim
 
Intro to computer vision in .net update
Intro to computer vision in .net   updateIntro to computer vision in .net   update
Intro to computer vision in .net update
Stephen Lorello
 

Similar to I phone勉強会 (2011.11.23) (20)

UIWebView Tips
UIWebView TipsUIWebView Tips
UIWebView Tips
Katsumi Kishikawa
 
Desenvolvimento iOS - Aula 4
Desenvolvimento iOS - Aula 4Desenvolvimento iOS - Aula 4
Desenvolvimento iOS - Aula 4
Saulo Arruda
 
iOS 7 SDK特訓班
iOS 7 SDK特訓班iOS 7 SDK特訓班
iOS 7 SDK特訓班
彼得潘 Pan
 
GCD in Action
GCD in ActionGCD in Action
GCD in Action
Nigel Barber
 
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефонаКурсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
Глеб Тарасов
 
Yahoo Open Source - The Tour & Mystery of AppDevKit (MOPCON 2016)
Yahoo Open Source - The Tour & Mystery of AppDevKit (MOPCON 2016)Yahoo Open Source - The Tour & Mystery of AppDevKit (MOPCON 2016)
Yahoo Open Source - The Tour & Mystery of AppDevKit (MOPCON 2016)
anistar sung
 
Webエンジニアから見たiOS5
Webエンジニアから見たiOS5Webエンジニアから見たiOS5
Webエンジニアから見たiOS5
Satoshi Asano
 
PhotoFlipCardView
PhotoFlipCardViewPhotoFlipCardView
PhotoFlipCardView
Katsumi Kishikawa
 
Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)
Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)
Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)
Sarp Erdag
 
Leaving Interface Builder Behind
Leaving Interface Builder BehindLeaving Interface Builder Behind
Leaving Interface Builder Behind
John Wilker
 
Intro to HTML5
Intro to HTML5Intro to HTML5
Intro to HTML5
Jussi Pohjolainen
 
UIViewControllerのコーナーケース
UIViewControllerのコーナーケースUIViewControllerのコーナーケース
UIViewControllerのコーナーケース
Katsumi Kishikawa
 
Android workshop
Android workshopAndroid workshop
Android workshop
Michael Galpin
 
Cocoa Heads Tricity - Design Patterns
Cocoa Heads Tricity - Design PatternsCocoa Heads Tricity - Design Patterns
Cocoa Heads Tricity - Design Patterns
Maciej Burda
 
Developing iOS REST Applications
Developing iOS REST ApplicationsDeveloping iOS REST Applications
Developing iOS REST Applications
lmrei
 
CakePHP in iPhone App
CakePHP in iPhone AppCakePHP in iPhone App
CakePHP in iPhone App
Akihiro Matsuura
 
Mobile App Development: Primi passi con NativeScript e Angular 2
Mobile App Development: Primi passi con NativeScript e Angular 2Mobile App Development: Primi passi con NativeScript e Angular 2
Mobile App Development: Primi passi con NativeScript e Angular 2
Filippo Matteo Riggio
 
Synchronizing without internet - Multipeer Connectivity (iOS)
Synchronizing without internet - Multipeer Connectivity (iOS)Synchronizing without internet - Multipeer Connectivity (iOS)
Synchronizing without internet - Multipeer Connectivity (iOS)
Jorge Maroto
 
iPhone/iPad开发讲座 第五讲 定制视图和多点触摸
iPhone/iPad开发讲座 第五讲 定制视图和多点触摸iPhone/iPad开发讲座 第五讲 定制视图和多点触摸
iPhone/iPad开发讲座 第五讲 定制视图和多点触摸
Hao Peiqiang
 
Creating an Uber Clone - Part XXIV - Transcript.pdf
Creating an Uber Clone - Part XXIV - Transcript.pdfCreating an Uber Clone - Part XXIV - Transcript.pdf
Creating an Uber Clone - Part XXIV - Transcript.pdf
ShaiAlmog1
 
Desenvolvimento iOS - Aula 4
Desenvolvimento iOS - Aula 4Desenvolvimento iOS - Aula 4
Desenvolvimento iOS - Aula 4
Saulo Arruda
 
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефонаКурсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
Глеб Тарасов
 
Yahoo Open Source - The Tour & Mystery of AppDevKit (MOPCON 2016)
Yahoo Open Source - The Tour & Mystery of AppDevKit (MOPCON 2016)Yahoo Open Source - The Tour & Mystery of AppDevKit (MOPCON 2016)
Yahoo Open Source - The Tour & Mystery of AppDevKit (MOPCON 2016)
anistar sung
 
Webエンジニアから見たiOS5
Webエンジニアから見たiOS5Webエンジニアから見たiOS5
Webエンジニアから見たiOS5
Satoshi Asano
 
Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)
Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)
Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)
Sarp Erdag
 
Leaving Interface Builder Behind
Leaving Interface Builder BehindLeaving Interface Builder Behind
Leaving Interface Builder Behind
John Wilker
 
UIViewControllerのコーナーケース
UIViewControllerのコーナーケースUIViewControllerのコーナーケース
UIViewControllerのコーナーケース
Katsumi Kishikawa
 
Cocoa Heads Tricity - Design Patterns
Cocoa Heads Tricity - Design PatternsCocoa Heads Tricity - Design Patterns
Cocoa Heads Tricity - Design Patterns
Maciej Burda
 
Developing iOS REST Applications
Developing iOS REST ApplicationsDeveloping iOS REST Applications
Developing iOS REST Applications
lmrei
 
Mobile App Development: Primi passi con NativeScript e Angular 2
Mobile App Development: Primi passi con NativeScript e Angular 2Mobile App Development: Primi passi con NativeScript e Angular 2
Mobile App Development: Primi passi con NativeScript e Angular 2
Filippo Matteo Riggio
 
Synchronizing without internet - Multipeer Connectivity (iOS)
Synchronizing without internet - Multipeer Connectivity (iOS)Synchronizing without internet - Multipeer Connectivity (iOS)
Synchronizing without internet - Multipeer Connectivity (iOS)
Jorge Maroto
 
iPhone/iPad开发讲座 第五讲 定制视图和多点触摸
iPhone/iPad开发讲座 第五讲 定制视图和多点触摸iPhone/iPad开发讲座 第五讲 定制视图和多点触摸
iPhone/iPad开发讲座 第五讲 定制视图和多点触摸
Hao Peiqiang
 
Creating an Uber Clone - Part XXIV - Transcript.pdf
Creating an Uber Clone - Part XXIV - Transcript.pdfCreating an Uber Clone - Part XXIV - Transcript.pdf
Creating an Uber Clone - Part XXIV - Transcript.pdf
ShaiAlmog1
 

Recently uploaded (20)

SECURE BLOCKCHAIN FOR ADMISSION PROCESSING IN EDUCATIONAL INSTITUTIONS.pdf
SECURE BLOCKCHAIN FOR ADMISSION PROCESSING IN EDUCATIONAL INSTITUTIONS.pdfSECURE BLOCKCHAIN FOR ADMISSION PROCESSING IN EDUCATIONAL INSTITUTIONS.pdf
SECURE BLOCKCHAIN FOR ADMISSION PROCESSING IN EDUCATIONAL INSTITUTIONS.pdf
spub1985
 
Combining Lexical and Semantic Search with Milvus 2.5
Combining Lexical and Semantic Search with Milvus 2.5Combining Lexical and Semantic Search with Milvus 2.5
Combining Lexical and Semantic Search with Milvus 2.5
Zilliz
 
TrustArc Webinar: State of State Privacy Laws
TrustArc Webinar: State of State Privacy LawsTrustArc Webinar: State of State Privacy Laws
TrustArc Webinar: State of State Privacy Laws
TrustArc
 
Revolutionizing Field Service: How LLMs Are Powering Smarter Knowledge Access...
Revolutionizing Field Service: How LLMs Are Powering Smarter Knowledge Access...Revolutionizing Field Service: How LLMs Are Powering Smarter Knowledge Access...
Revolutionizing Field Service: How LLMs Are Powering Smarter Knowledge Access...
Earley Information Science
 
AMER Introduction to ThousandEyes Webinar
AMER Introduction to ThousandEyes WebinarAMER Introduction to ThousandEyes Webinar
AMER Introduction to ThousandEyes Webinar
ThousandEyes
 
16 KALALU🕉️🏇🪓🪈🏹👑👑👑👑👑🤴🦁💿✈️🛸🚀🪩🥏🍥 APARAMAHASAHASRA SIMHAMAHANKALKIADIPARASAKTIBH...
16 KALALU🕉️🏇🪓🪈🏹👑👑👑👑👑🤴🦁💿✈️🛸🚀🪩🥏🍥 APARAMAHASAHASRA SIMHAMAHANKALKIADIPARASAKTIBH...16 KALALU🕉️🏇🪓🪈🏹👑👑👑👑👑🤴🦁💿✈️🛸🚀🪩🥏🍥 APARAMAHASAHASRA SIMHAMAHANKALKIADIPARASAKTIBH...
16 KALALU🕉️🏇🪓🪈🏹👑👑👑👑👑🤴🦁💿✈️🛸🚀🪩🥏🍥 APARAMAHASAHASRA SIMHAMAHANKALKIADIPARASAKTIBH...
IT Industry
 
Teaching Prompting and Prompt Sharing to End Users.pptx
Teaching Prompting and Prompt Sharing to End Users.pptxTeaching Prompting and Prompt Sharing to End Users.pptx
Teaching Prompting and Prompt Sharing to End Users.pptx
Michael Blumenthal (Microsoft MVP)
 
Leadership u automatizaciji: RPA priče iz prakse!
Leadership u automatizaciji: RPA priče iz prakse!Leadership u automatizaciji: RPA priče iz prakse!
Leadership u automatizaciji: RPA priče iz prakse!
UiPathCommunity
 
Kickstart Your QA: An Introduction to Automated Regression Testing Tools
Kickstart Your QA: An Introduction to Automated Regression Testing ToolsKickstart Your QA: An Introduction to Automated Regression Testing Tools
Kickstart Your QA: An Introduction to Automated Regression Testing Tools
Shubham Joshi
 
Dev Dives: Unlock the future of automation with UiPath Agent Builder
Dev Dives: Unlock the future of automation with UiPath Agent BuilderDev Dives: Unlock the future of automation with UiPath Agent Builder
Dev Dives: Unlock the future of automation with UiPath Agent Builder
UiPathCommunity
 
Benchmark Testing Demystified: Your Roadmap to Peak Performance
Benchmark Testing Demystified: Your Roadmap to Peak PerformanceBenchmark Testing Demystified: Your Roadmap to Peak Performance
Benchmark Testing Demystified: Your Roadmap to Peak Performance
Shubham Joshi
 
Blockchain for Businesses Practical Use Cases & Benefits.pdf
Blockchain for Businesses Practical Use Cases & Benefits.pdfBlockchain for Businesses Practical Use Cases & Benefits.pdf
Blockchain for Businesses Practical Use Cases & Benefits.pdf
Yodaplus Technologies Private Limited
 
William Maclyn Murphy McRae - A Seasoned Professional Renowned
William Maclyn Murphy McRae - A Seasoned Professional RenownedWilliam Maclyn Murphy McRae - A Seasoned Professional Renowned
William Maclyn Murphy McRae - A Seasoned Professional Renowned
William Maclyn Murphy McRae
 
Bedrock Data Automation (Preview): Simplifying Unstructured Data Processing
Bedrock Data Automation (Preview): Simplifying Unstructured Data ProcessingBedrock Data Automation (Preview): Simplifying Unstructured Data Processing
Bedrock Data Automation (Preview): Simplifying Unstructured Data Processing
Zilliz
 
Not a Kubernetes fan? The state of PaaS in 2025
Not a Kubernetes fan? The state of PaaS in 2025Not a Kubernetes fan? The state of PaaS in 2025
Not a Kubernetes fan? The state of PaaS in 2025
Anthony Dahanne
 
What is FinTech A Complete Guide to Financial Technology.pdf
What is FinTech A Complete Guide to Financial Technology.pdfWhat is FinTech A Complete Guide to Financial Technology.pdf
What is FinTech A Complete Guide to Financial Technology.pdf
Yodaplus Technologies Private Limited
 
Temporary Compound microscope slide .pptx
Temporary Compound microscope slide .pptxTemporary Compound microscope slide .pptx
Temporary Compound microscope slide .pptx
Samir Sharma
 
Understanding & Utilizing SharePoint Advanced Management
Understanding & Utilizing SharePoint Advanced ManagementUnderstanding & Utilizing SharePoint Advanced Management
Understanding & Utilizing SharePoint Advanced Management
Drew Madelung
 
NSFW AI Chatbot Development Costs: What You Need to Know
NSFW AI Chatbot Development Costs: What You Need to KnowNSFW AI Chatbot Development Costs: What You Need to Know
NSFW AI Chatbot Development Costs: What You Need to Know
Soulmaite
 
Caching for Performance Masterclass: Caching at Scale
Caching for Performance Masterclass: Caching at ScaleCaching for Performance Masterclass: Caching at Scale
Caching for Performance Masterclass: Caching at Scale
ScyllaDB
 
SECURE BLOCKCHAIN FOR ADMISSION PROCESSING IN EDUCATIONAL INSTITUTIONS.pdf
SECURE BLOCKCHAIN FOR ADMISSION PROCESSING IN EDUCATIONAL INSTITUTIONS.pdfSECURE BLOCKCHAIN FOR ADMISSION PROCESSING IN EDUCATIONAL INSTITUTIONS.pdf
SECURE BLOCKCHAIN FOR ADMISSION PROCESSING IN EDUCATIONAL INSTITUTIONS.pdf
spub1985
 
Combining Lexical and Semantic Search with Milvus 2.5
Combining Lexical and Semantic Search with Milvus 2.5Combining Lexical and Semantic Search with Milvus 2.5
Combining Lexical and Semantic Search with Milvus 2.5
Zilliz
 
TrustArc Webinar: State of State Privacy Laws
TrustArc Webinar: State of State Privacy LawsTrustArc Webinar: State of State Privacy Laws
TrustArc Webinar: State of State Privacy Laws
TrustArc
 
Revolutionizing Field Service: How LLMs Are Powering Smarter Knowledge Access...
Revolutionizing Field Service: How LLMs Are Powering Smarter Knowledge Access...Revolutionizing Field Service: How LLMs Are Powering Smarter Knowledge Access...
Revolutionizing Field Service: How LLMs Are Powering Smarter Knowledge Access...
Earley Information Science
 
AMER Introduction to ThousandEyes Webinar
AMER Introduction to ThousandEyes WebinarAMER Introduction to ThousandEyes Webinar
AMER Introduction to ThousandEyes Webinar
ThousandEyes
 
16 KALALU🕉️🏇🪓🪈🏹👑👑👑👑👑🤴🦁💿✈️🛸🚀🪩🥏🍥 APARAMAHASAHASRA SIMHAMAHANKALKIADIPARASAKTIBH...
16 KALALU🕉️🏇🪓🪈🏹👑👑👑👑👑🤴🦁💿✈️🛸🚀🪩🥏🍥 APARAMAHASAHASRA SIMHAMAHANKALKIADIPARASAKTIBH...16 KALALU🕉️🏇🪓🪈🏹👑👑👑👑👑🤴🦁💿✈️🛸🚀🪩🥏🍥 APARAMAHASAHASRA SIMHAMAHANKALKIADIPARASAKTIBH...
16 KALALU🕉️🏇🪓🪈🏹👑👑👑👑👑🤴🦁💿✈️🛸🚀🪩🥏🍥 APARAMAHASAHASRA SIMHAMAHANKALKIADIPARASAKTIBH...
IT Industry
 
Leadership u automatizaciji: RPA priče iz prakse!
Leadership u automatizaciji: RPA priče iz prakse!Leadership u automatizaciji: RPA priče iz prakse!
Leadership u automatizaciji: RPA priče iz prakse!
UiPathCommunity
 
Kickstart Your QA: An Introduction to Automated Regression Testing Tools
Kickstart Your QA: An Introduction to Automated Regression Testing ToolsKickstart Your QA: An Introduction to Automated Regression Testing Tools
Kickstart Your QA: An Introduction to Automated Regression Testing Tools
Shubham Joshi
 
Dev Dives: Unlock the future of automation with UiPath Agent Builder
Dev Dives: Unlock the future of automation with UiPath Agent BuilderDev Dives: Unlock the future of automation with UiPath Agent Builder
Dev Dives: Unlock the future of automation with UiPath Agent Builder
UiPathCommunity
 
Benchmark Testing Demystified: Your Roadmap to Peak Performance
Benchmark Testing Demystified: Your Roadmap to Peak PerformanceBenchmark Testing Demystified: Your Roadmap to Peak Performance
Benchmark Testing Demystified: Your Roadmap to Peak Performance
Shubham Joshi
 
William Maclyn Murphy McRae - A Seasoned Professional Renowned
William Maclyn Murphy McRae - A Seasoned Professional RenownedWilliam Maclyn Murphy McRae - A Seasoned Professional Renowned
William Maclyn Murphy McRae - A Seasoned Professional Renowned
William Maclyn Murphy McRae
 
Bedrock Data Automation (Preview): Simplifying Unstructured Data Processing
Bedrock Data Automation (Preview): Simplifying Unstructured Data ProcessingBedrock Data Automation (Preview): Simplifying Unstructured Data Processing
Bedrock Data Automation (Preview): Simplifying Unstructured Data Processing
Zilliz
 
Not a Kubernetes fan? The state of PaaS in 2025
Not a Kubernetes fan? The state of PaaS in 2025Not a Kubernetes fan? The state of PaaS in 2025
Not a Kubernetes fan? The state of PaaS in 2025
Anthony Dahanne
 
Temporary Compound microscope slide .pptx
Temporary Compound microscope slide .pptxTemporary Compound microscope slide .pptx
Temporary Compound microscope slide .pptx
Samir Sharma
 
Understanding & Utilizing SharePoint Advanced Management
Understanding & Utilizing SharePoint Advanced ManagementUnderstanding & Utilizing SharePoint Advanced Management
Understanding & Utilizing SharePoint Advanced Management
Drew Madelung
 
NSFW AI Chatbot Development Costs: What You Need to Know
NSFW AI Chatbot Development Costs: What You Need to KnowNSFW AI Chatbot Development Costs: What You Need to Know
NSFW AI Chatbot Development Costs: What You Need to Know
Soulmaite
 
Caching for Performance Masterclass: Caching at Scale
Caching for Performance Masterclass: Caching at ScaleCaching for Performance Masterclass: Caching at Scale
Caching for Performance Masterclass: Caching at Scale
ScyllaDB
 

I phone勉強会 (2011.11.23)

  • 3. iPhone SDK • touch • on the WEB •LDR touch • • •i-Radio •LCD Clock • •Subway Map • •MyWebClip • •
  • 4. iPhone SDK http://github.com/kishikawakatsumi •hatena-touch •DescriptionBuilder •ldr-touch •TiledLayerView •tv-listings •UICCalendarPicker •MapKit-Route-Directions •FlipCardNavigationView •PhotoFlipCardView
  • 11. iPhone SDK #import <UIKit/UIKit.h> extern NSString * const FFNavigationBarSwipedNotification; @interface FFNavigationBar : UINavigationBar @end
  • 12. #import "FFNavigationBar.h" @implementation FFNavigationBar iPhone SDK - (void)initCommon { self.barStyle = UIBarStyleBlack; } - (id)init { self = [super init]; if (self) { [self initCommon]; } return self; } - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self initCommon]; } return self; }
  • 13. - (id)initWithCoder:(NSCoder *)coder { self = [super initWithCoder:coder]; iPhone SDK if (self) { [self initCommon]; } return self; } - (void)drawRect:(CGRect)rect { [background drawAsPatternInRect:rect]; } @end
  • 24. iPhone SDK UIImage draw~ PNG http://sonson.jp/?p=745 PNG => UI => =>JPEG
  • 25. iPhone SDK CALayer *backgroundImageLayer = [CALayer layer]; backgroundImageLayer.frame = CGRectMake(17.0f, 12.0f, 285.0f, 310.0f); backgroundImageLayer.contents = (id)[[UIImage imageNamed:@"photo_bg.png"] CGImage]; [self.contentView.layer addSublayer:backgroundImageLayer]; photoImageView = [[UIImageView alloc] initWithFrame:CGRectMake(30.0f, 18.0f, 260.0f, 260.0f)]; photoImageView.backgroundColor = [UIColor clearColor]; [self.contentView addSubview:photoImageView]; [photoImageView release];
  • 26. iPhone SDK preloaderBackground = [[UIImageView alloc] initWithFrame:CGRectMake(95.0f, 95.0f, 70.0f, 70.0f)]; preloaderBackground.backgroundColor = [UIColor clearColor]; preloaderBackground.image = [UIImage imageNamed:@"photo_preloader.png"]; [photoImageView addSubview:preloaderBackground]; [preloaderBackground release]; preloader = [[FFPreloaderView alloc] initWithFrame:CGRectMake(5.0f, 1.0f, 60.0f, 20.0f)]; [preloaderBackground addSubview:preloader]; [preloader release];
  • 27. iPhone SDK CALayer *shadowLayer = [CALayer layer]; shadowLayer.frame = CGRectMake(30.0f, 18.0f, 260.0f, 260.0f); shadowLayer.contents = (id)[[UIImage imageNamed:@"photo_shadow.png"] CGImage]; [cellContentView.layer addSublayer:shadowLayer]; favoriteButton = [[FFFavoriteButton alloc] initWithFrame:CGRectMake(19.0f, 24.0f, 75.0f, 29.0f)]; favoriteButton.exclusiveTouch = YES;
  • 29. iPhone SDK NSCache NSDictionary
  • 30. @interface FFImageCache : NSObject { NSFileManager *fileManager; iPhone SDK NSString *cacheDirectory; NSCache *cache; } + (FFImageCache *)sharedInstance; - (UIImage *)cachedImageWithURL:(NSString *)URL; - (UIImage *)cachedImageWithURL:(NSString *)URL defaultImage:(UIImage *)defaultImage; - (UIImage *)cachedImageWithURL:(NSString *)URL size:(NSInteger)size; - (UIImage *)cachedImageWithURL:(NSString *)URL size:(NSInteger)size defaultImage:(UIImage *)defaultImage; - (void)storeImage:(UIImage *)image data:(NSData *)data URL:(NSString *)URL; - (void)purgeMemoryCache; - (void)deleteAllCacheFiles; @end
  • 32. - (UIImage *)cachedImageWithURL:(NSString *)URL defaultImage:(UIImage *)defaultImage { iPhone SDK NSString *key = [FFImageCache keyForURL:URL]; UIImage *cachedImage = [cache objectForKey:key]; if (cachedImage) { return cachedImage; } cachedImage = [UIImage imageWithContentsOfFile:[self pathForKey:key]]; if (cachedImage) { [cache setObject:cachedImage forKey:key]; } return cachedImage; } - (void)storeImage:(UIImage *)image data:(NSData *)data URL:(NSString *)URL { NSString *key = [FFImageCache keyForURL:URL]; [cache setObject:image forKey:key]; [data writeToFile:[self pathForKey:key] atomically:NO]; }
  • 33. + (NSString *)keyForURL:(NSString *)URL { ! if ([URL length] == 0) { ! ! ! } iPhone SDK return nil; ! const char *cStr = [URL UTF8String]; ! unsigned char result[16]; ! CC_MD5(cStr, (CC_LONG)strlen(cStr), result); ! return [NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7],result[8], result[9], result[10], result[11],result[12], result[13], result[14], result[15]]; ! }
  • 36. - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { iPhone SDK if (!scrollView.isDecelerating) { contentOffsetY = scrollView.contentOffset.y; } } - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { shouldSnapScroll = scrollView.isTracking && scrollView.isDragging && ! scrollView.isDecelerating; if (!decelerate) { [self loadImagesForOnscreenRows]; } }
  • 37. - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { [self loadImagesForOnscreenRows]; iPhone SDK CGFloat distance = ABS(distance = contentOffsetY - scrollView.contentOffset.y); if (distance > timelineView.frame.size.height * 2) { shouldSnapScroll = YES; } if (!shouldSnapScroll) { return; } NSArray *indexPaths = timelineView.indexPathsForVisibleRows; if ([indexPaths count] == 0) { return; } if (contentOffsetY > scrollView.contentOffset.y) { scrollDirection = ScrollDirectionUp; } else { scrollDirection = ScrollDirectionDown; }
  • 38. CGFloat delta; NSIndexPath *indexPath; if (scrollDirection == ScrollDirectionUp) { iPhone SDK indexPath = [indexPaths objectAtIndex:0]; CGRect rect = [timelineView rectForSection:indexPath.section]; delta = scrollView.contentOffset.y - rect.origin.y; if (delta > 250.0f) { indexPath = [indexPaths lastObject]; rect = [timelineView rectForSection:indexPath.section]; delta = rect.origin.y - scrollView.contentOffset.y; if (delta < 0.0f) { return; } } } else { indexPath = [indexPaths lastObject]; CGRect rect = [timelineView rectForSection:indexPath.section]; delta = rect.origin.y - scrollView.contentOffset.y; if (indexPath.section == [timelineManager count] - 1) { return; } if (delta < 0.0f) { return; } if (delta > 200.0f) { indexPath = [indexPaths objectAtIndex:0]; } } if (scrollView.contentInset.top < 60.0f && scrollView.contentOffset.y > 0.0f) { NSIndexPath *toIndexPath = [NSIndexPath indexPathForRow:0 inSection:indexPath.section]; [timelineView scrollToRowAtIndexPath:toIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; } }
  • 42. - (void)animateIcon:(BOOL)flag { [UIView transitionFromView:flag ? icon : selectedIcon iPhone SDK toView:flag ? selectedIcon : icon duration:0.4 options:UIViewAnimationOptionTransitionFlipFromRight | UIViewAnimationOptionShowHideTransitionViews completion: ^(BOOL finished) { if (!animaitionFinished) { [self animateIcon:!flag]; } }]; } - (void)setEnabled:(BOOL)enabled { [super setEnabled:enabled]; if (enabled) { animaitionFinished = YES; } else { animaitionFinished = NO; shouldStartZoomAnimation = YES; [self animateIcon:self.selected]; } }
  • 43. - (void)setSelected:(BOOL)selected { [super setSelected:selected]; if (selected) { iPhone SDK icon.hidden = YES; selectedIcon.hidden = NO; animationIcon.image = [UIImage imageNamed:@"button_favorite_icon_selected.png"]; } else { icon.hidden = NO; selectedIcon.hidden = YES; animationIcon.image = [UIImage imageNamed:@"button_favorite_icon.png"]; } if (shouldStartZoomAnimation) { shouldStartZoomAnimation = NO; CABasicAnimation *zoom = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; zoom.toValue = [NSNumber numberWithFloat:8.0f]; CABasicAnimation *fade = [CABasicAnimation animationWithKeyPath:@"opacity"]; fade.toValue = [NSNumber numberWithFloat:0.0f]; CAAnimationGroup *group = [CAAnimationGroup animation]; group.delegate = self; group.animations = [NSArray arrayWithObjects:zoom, fade, nil]; group.duration = 0.5; animationIcon.hidden = NO; [animationIcon.layer addAnimation:group forKey:nil]; } } - (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag { animationIcon.hidden = YES; }
  • 46. photoScrollView = [[UITableView alloc] initWithFrame:CGRectMake(6.0f, 30.0f, 50.0f, 264.0f)]; iPhone SDK photoScrollView.delegate = self; photoScrollView.dataSource = self; photoScrollView.rowHeight = 44.0f; photoScrollView.separatorColor = [UIColor clearColor]; photoScrollView.pagingEnabled = YES; photoScrollView.showsHorizontalScrollIndicator = NO; photoScrollView.showsVerticalScrollIndicator = NO; photoScrollView.backgroundColor = [UIColor clearColor]; photoScrollView.transform = CGAffineTransformMakeRotation(M_PI / -2.0f); photoScrollView.center = CGPointMake(146.0f, 56.0f); [cellContentView addSubview:photoScrollView]; [photoScrollView release]; pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(12.0f, 72.0f, 264.0f, 36.0f)]; pageControl.clipsToBounds = YES; pageControl.hidesForSinglePage = YES; pageControl.userInteractionEnabled = NO; [cellContentView addSubview:pageControl]; [pageControl release]; UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scrollViewTapped:)]; [photoScrollView addGestureRecognizer:tapRecognizer]; [tapRecognizer release];
  • 47. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; iPhone SDK } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section { NSUInteger count = [photos count]; if (count == 0) { pageControl.numberOfPages = 0; } else { pageControl.numberOfPages = MIN(count / 6 + 1, 17) ; } pageControl.currentPage = 0; return count; }
  • 48. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { iPhone SDK NSUInteger count = [photos count]; NSUInteger numPages = count / 6 + 1; photoScrollView.contentSize = CGSizeMake(50.0f, 264.0f * numPages); static NSString *cellIdentifier = @"Cell"; FFMyPhotoImageCell *cell = (FFMyPhotoImageCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (cell == nil) { cell = [[[FFMyPhotoImageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]autorelease]; cell.selectionStyle = UITableViewCellSelectionStyleNone; } cell.URL = [[photos objectAtIndex:indexPath.row] objectForKey:FFURLKey]; return cell; }
  • 49. - (void)scrollViewDidScroll:(UIScrollView *)sender { if (pageControlUsed) { iPhone SDK return; } CGFloat pageWidth = photoScrollView.bounds.size.height; int page = floor((photoScrollView.contentOffset.y - pageWidth / 2) / pageWidth) + 1; ! currentPage = MIN(page, 16); } - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { pageControlUsed = NO; pageControl.currentPage = currentPage; } - (void)scrollViewTapped:(UIGestureRecognizer *)gestureRecognizer { UITableView *tableView = (UITableView *)self.superview; [tableView.delegate tableView:tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection: 0]]; }
  • 51. CGFloat x = 41.0f; CGSize size; iPhone SDK NSString *username = user.username; if ([username length] > 0) { UIFont *commentUsernameFont = [FFConstants commentUsernameFont]; size = [username sizeWithFont:commentUsernameFont forWidth:253.0f - x lineBreakMode:UILineBreakModeTailTruncation]; [username drawInRect:CGRectMake(x, 6.0f, size.width, 12.0f) withFont:commentUsernameFont lineBreakMode:UILineBreakModeTailTruncation alignment:UITextAlignmentLeft]; x += size.width; NSString *action = NSLocalizedString(@" faved.", nil); UIFont *commentFont = [FFConstants commentFont]; size = [action sizeWithFont:commentFont forWidth:253.0f - x lineBreakMode:UILineBreakModeClip]; [action drawInRect:CGRectMake(x, 6.0f, size.width, 12.0f) withFont:commentFont lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentLeft]; NSMutableString *str = [NSMutableString string]; NSUInteger index = 0; NSUInteger length = [action length];; for (; index < length; index++) { [str appendString:[action substringWithRange:NSMakeRange(index, 1)]]; CGSize sz = [str sizeWithFont:commentFont forWidth:253.0f - x lineBreakMode:UILineBreakModeClip]; if (sz.width >= size.width) { index++; break; } } action = [action substringWithRange:NSMakeRange(index, length - index)]; [action drawInRect:CGRectMake(41.0f, 22.0f, 212.0f, 12.0f) withFont:commentFont lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentLeft]; }

Editor's Notes