1. 程式人生 > >[iOS_Dev] UITableView 水平放置 自動迴圈滾動

[iOS_Dev] UITableView 水平放置 自動迴圈滾動

//table  原創 http://blog.csdn.net/u014558625/

- (id)initWithFrame:(CGRect)frameOfHorizontalTwoTableView style:(UITableViewStyle)style
{
    float x = frameOfHorizontalTwoTableView.origin.x;
    float y = frameOfHorizontalTwoTableView.origin.y;
    float w = frameOfHorizontalTwoTableView.size.width;
    float h = frameOfHorizontalTwoTableView.size.height;
    float xOrigin = x + (w - h)/2;
    float yOrigin = y + (h - w)/2;
    float width   = h;
    float height  = w;
    CGRect horizontalTwoTableViewFrame = CGRectMake(xOrigin, yOrigin, width, height);
    
    self = [super initWithFrame:horizontalTwoTableViewFrame style:style];
    if (self) {
        self.transform = CGAffineTransformMakeRotation(-M_PI/2);//這是關鍵,水平放置的table
        /** 
         *  列印
         *  (CGRect) horizontalTwoTableViewFrame = origin=(x=349.5, y=-349.5) size=(width=325, height=1024)
         *  <HorizontalTwoTableView: 0x79358a00; baseClass = UITableView; frame = (0 0; 1024 325); transform = [0, -1, 1, 0, 0, 0];
         **/
        //
        self.lastScrolledIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
        self.lastHighlightedIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
        //
    }
    return self;
}


#import "HorizontalTwoTableViewCell.h"

#define kHorizontalTwoTableViewCellRotatedViewTag 200

@interface HorizontalTwoTableViewCell ()

@property (nonatomic, retain)AdvertisementEntity *contentEntity;
@property (nonatomic, retain)UIImageView         *selectedImageView;
@property (nonatomic, retain)DynamicImageView    *theImageView;
@end



// cell  <span style="font-family: Arial, Helvetica, sans-serif;">原創 http://blog.csdn.net/u014558625/</span>

@implementation HorizontalTwoTableViewCell


-(void)dealloc
{
    self.contentEntity = nil;
    
    self.selectedImageView = nil;
    self.theImageView = nil;
    
    [super dealloc];
}
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self)
    {
        // Initialization code
        
        self.accessoryType = UITableViewCellAccessoryNone;
        self.selectionStyle = UITableViewCellSelectionStyleNone;
        self.backgroundColor = [UIColor clearColor];
        self.contentView.backgroundColor = [UIColor clearColor];
        

        UIView *rotatedView          = [[[UIView alloc] init] autorelease];//(該檢視將被旋轉M_PI/2)
        rotatedView.backgroundColor	 = [UIColor clearColor];
        
        rotatedView.tag = kHorizontalTwoTableViewCellRotatedViewTag;
        [self.contentView addSubview:rotatedView];
        
        
        
        _selectedImageView = [[UIImageView alloc] init];
        _selectedImageView.hidden = YES;
        [rotatedView addSubview:_selectedImageView];
        
        
        _theImageView = [[DynamicImageView alloc] init];
        _theImageView.backgroundColor = [UIColor clearColor];
        [rotatedView addSubview:_theImageView];
        
        
        //一定要呼叫 setCellContentFrame來初始化檢視frame
    }
    return self;
}

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
    [super setHighlighted:highlighted animated:animated];
    
    if (highlighted)
    {
        [self darkenImageWithUIGestureRecognizerState:UIGestureRecognizerStateChanged];
    }
    else
    {
        [self darkenImageWithUIGestureRecognizerState:UIGestureRecognizerStateEnded];
    }
    
    DDLogVerbose(@"%@ %@", THIS_FILE,THIS_METHOD);
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];
    
    
    DDLogVerbose(@"%@ %@", THIS_FILE,THIS_METHOD);
}


#pragma mark -
#pragma mark - designated

//適配 iphone6+ 6 5S 4, 對應螢幕尺寸5.5  4.7  4  3.5
- (void)setCellContentFrame:(CGRect)cellContentFrame cellPadding:(CGFloat)cellPaddingFloat;
{
    //cellContentFrame是水平放置的table中cell的自定義frame,cellPaddingFloat是單元格上下的空隙
    
    //因為 使用這個cell的table被旋轉-M_PI/2 變成水平放置的table,
    //所以 這個單元格也是水平放置的,單元格內容也同時變成水平的;
    //但是 在initWithStyle方法中,單元格的內容都被addSubview到rotatedView(該檢視將被旋轉M_PI/2,此時還沒有旋轉)
    //所以 單元格還是水平放置的,而單元格的內容恢復成縱向的。
    
    //所以 cellContentFrame是水平放置的table中cell的自定義frame,
    
    
    // 4寸螢幕的情況
    // 假設 cellContentFrame = CGRectMake(0, 0, 370, 250)    cellPaddingFloat = 8.0
    // 那麼 CGRect rotatedViewRect = CGRectMake(68, -68+8, 234.0, 370.0);
    
    // 計算過程如下
    // 水平放置的單元格,寬370,高250;  內容檢視contentView,寬370,高234;  250-8*2=234;(水平單元格的上下空隙各8)
    // xOrigin:(370-234)/2=68  yOrigin:(234-370)/2=-68(然後 -68+8,8是水平單元格的上面空隙);
    // 旋轉M_PI/2, width,height 互換, 所以 rotatedViewRect 就是 (xOrigin, yOrigin, height, width) = (68, -68+8, 234.0, 370)
    
    // 還記得嗎? 單元格的內容恢復成縱向.
    // selectedImageView.frame = CGRectMake(0, 0, 234, 370);
    // imageButton.frame = CGRectMake(8, 8, 234-16, 370-8-30);  //30預留給label
    // titleLabel.frame = CGRectMake(0, 370-30+6, 234, 30-6-8);
    
    
    float width   = cellContentFrame.size.width;
    float height  = cellContentFrame.size.height - cellPaddingFloat*2;
    float xOrigin = cellContentFrame.origin.x + (width - height)/2;
    float yOrigin = cellContentFrame.origin.y + (height - width)/2 + cellPaddingFloat;
    
    UIView *rotatedView = (UIView *)[self.contentView viewWithTag:kHorizontalTwoTableViewCellRotatedViewTag];
    rotatedView.frame = CGRectMake(xOrigin, yOrigin, height, width);
    rotatedView.transform = CGAffineTransformMakeRotation(M_PI/2); //這個很關鍵,與使用這個cell的table旋轉方向相反,旋轉角度大小相同
    
    // 還記得嗎? 單元格的內容恢復成縱向.
    float contentWidth  = height;
    float contentHeight = width;
    _selectedImageView.frame = CGRectMake(0, 0, contentWidth, contentHeight);
    _theImageView.frame = CGRectMake(0, 0, contentWidth, contentHeight);
}

- (void)setCellContentFrame:(CGRect)cellContentFrame
{
    [self setCellContentFrame:cellContentFrame cellPadding:4.0f];
}


#pragma mark -
#pragma mark -  setters

-(void)setShowSelectImageView:(BOOL)show
{
    _showSelectImageView = show;
    if (_showSelectImageView)
    {
        _selectedImageView.hidden = NO;
    }
    else
    {
        _selectedImageView.hidden = YES;
    }
}


#pragma mark -
#pragma mark - 自定義

- (void)darkenImageWithUIGestureRecognizerState:(UIGestureRecognizerState)aState
{//使圖片變暗
    switch (aState)
    {
        case UIGestureRecognizerStateBegan: // object pressed
        case UIGestureRecognizerStateChanged:
            _theImageView.layer.backgroundColor = [UIColor blackColor].CGColor;
            _theImageView.layer.opacity = 0.4;
            break;
            
        case UIGestureRecognizerStateEnded: // object released
            _theImageView.layer.backgroundColor = [UIColor clearColor].CGColor;
            _theImageView.layer.opacity = 1.0;
            break;
            
        default: // unknown tap
            DDLogVerbose(@"longPressGR.state %i", aState);
            break;
    }
}

- (UIImage *)imageWithColor:(UIColor *)color
{
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return theImage;
}


#pragma mark - 
#pragma mark - dataSource

- (void)updateDataSource:(AdvertisementEntity *)aADEntity
{
    //清除快取
    _theImageView.image = nil;
    

    //更新資料來源
    self.contentEntity = aADEntity;
    if ( ! self.contentEntity) {
        // DDLogVerbose(@"updateDataSource: 沒有 資料啊!");
        return;
    }
    
    
    
    
    //TODO: test code
    _theImageView.image = [UIImage imageNamed:@"iphone"];
    //TODO: test code
    
    
    
    
    //繫結資料
    if ([self.contentEntity.adImageURL length])
    {
        [_theImageView updateImageModuleType:MODULE_TYPE_TASK Url:self.contentEntity.adImageURL withUid:self.contentEntity.adSID withDefaultImage:nil];
    }
    /**
    if ([self.contentEntity.thumbLocalPath length])
    {
        NSString *filePath = [SystemUtils imageMideaFilePathForFileName:self.contentEntity.thumbLocalPath];
        [_imageButton setBackgroundImage:[UIImage imageWithContentsOfFile:filePath] forState:UIControlStateNormal];
    }
    else if([self.contentEntity.thumbServerUrl length])
    {
        [self requestSmallImageForContentID:self.contentEntity.contentID URL:self.contentEntity.thumbServerUrl];
    }
    **/
}


/**
//描述:請求小圖片
//引數:aContentID內容ID,imageURL圖片路徑
- (void)requestSmallImageForContentID:(NSString *)aContentID URL:(NSString *)imageURL
{
    dispatch_async(kBgQueue,
    ^{
        NSDictionary *dic = [[BaseContentListManager sharedContentListModuleManager]
                             requestBlockSmallImageForContentID:aContentID
                             URL:imageURL];
        
        NSData *imageData = [dic objectForKey:@"ImageData"];
        if(imageData)
        {
            dispatch_sync(dispatch_get_main_queue(),
            ^{
                
                //顯示小圖
                DDLogVerbose(@"%@ %@ 顯示小圖",THIS_FILE,THIS_METHOD);
                if([self.contentEntity.contentID isEqualToString:[dic objectForKey:@"contentID"]])
                {
                    self.imageView.image = [UIImage imageWithData:imageData];
                }
                
                
            });
        }
        
    });
}
**/



@end


其實有個更簡單的:
首先:
   tableView.transform = CGAffineTransformMakeRotation(-M_PI/2);//這是關鍵,水平放置的table
然後:
   cell.contentView.transform = CGAffineTransformMakeRotation(M_PI/2);//這是關鍵




//轉載 http://stackoverflow.com/questions/10404116/uitableview-infinite-scrolling

'UITableView' is same as 'UIScrollView' in 'scrollViewDidScroll' method.

So, its easy to emulate infinite scrolling.

  1. double the array so that head and tail are joined together to emulate circular table

  2. use my following code to make user switch between 1st part of doubled table and 2nd part of doubled table when they tend to reach the start or the end of the table.

:

/* To emulate infinite scrolling...

The table data was doubled to join the head and tail: (suppose table had 1,2,3,4)
1 2 3 4|1 2 3 4 (actual data doubled)
---------------
1 2 3 4 5 6 7 8 (visualising joined table in eight parts)

When the user scrolls backwards to 1/8th of the joined table, user is actually at the 1/4th of actual data, so we scroll instantly (we take user) to the 5/8th of the joined table where the cells are exactly the same.

Similarly, when user scrolls to 6/8th of the table, we will scroll back to 2/8th where the cells are same. (I'm using 6/8th when 7/8th sound more logical because 6/8th is good for small tables.)

In simple words, when user reaches 1/4th of the first half of table, we scroll to 1/4th of the second half, when he reaches 2/4th of the second half of table, we scroll to the 2/4 of first half. This is done simply by subtracting OR adding half the length of the new/joined table.

 Written and posted by Anup Kattel. Feel free to use this code. Please keep these comments if you don't mind.
*/-(void)scrollViewDidScroll:(UIScrollView*)scrollView_ 
{CGFloat currentOffsetX = scrollView_.contentOffset.x;CGFloat currentOffSetY = scrollView_.contentOffset.y;CGFloat contentHeight = scrollView_.contentSize.height;if(currentOffSetY <(contentHeight /8.0)){
    scrollView_.contentOffset =CGPointMake(currentOffsetX,(currentOffSetY +(contentHeight/2)));}if(currentOffSetY >((contentHeight *6)/8.0)){
       scrollView_.contentOffset =CGPointMake(currentOffsetX,(currentOffSetY -(contentHeight/2)));}}