iphone-67-长按uitableview的row,实现reorder

来源:互联网 发布:java jdbc连接池使用 编辑:程序博客网 时间:2024/06/06 11:02

iphone-67-长按uitableview的row,实现reorder

 (2012-06-11 15:10:26)
转载
标签: 

iphone

 

reorder

 

cell

 

uitableview

 

长按

 

隐藏

 

it

分类: iPhone
http://b2cloud.com.au/how-to-guides/reordering-a-uitableviewcell-from-any-touch-point

A component of one of our upcoming apps is a Scramble type game where letters are rearranged to solve the word. I had a fantastic idea to use a UITableView flipped on it’s side with reordering enabled to make up the bulk of the Scramble reordering functionality. It worked without a hitch. During development we found that having the cell’s reordering grip only taking up a 44×44 square wasn’t very effective when our letters were a lot bigger, you would have to have your finger exactly in that small area in order to move the letters around. With a bit of magic I managed to make the reorder grip fill the entire cell, and this is how you do it:

Open the project startpoint and go to the LargeTableGripViewController.m. ThetableView:willDisplayCell:forRowAtIndexPath: is the place we will need to put the code. Firstly we’ll see what subviews are actually in our cell. NSLog all of them

NSLog(@"%@", cell.subviews);

Run the project and you will see a view called “UITableViewCellReorderControl” being logged. This is where the grip touches are handled. You may have never heard of UITableViewCellReorderControl, that’s because it is a private class that isn’t publicly accessible to developers.

Because we dont have the class definition for “UITableViewCellReorderControl“, we will check it’s string description while looping through the subviews to make sure we are only affecting the “UITableViewCellReorderControl” class.

for(UIView* view in cell.subviews){        if([[[view class] description] isEqualToString:@"UITableViewCellReorderControl"])        {                NSLog(@"%@", view);                [view setBackgroundColor:[UIColor redColor]];        }}

Run the project, only the “UITableViewCellReorderControl“s will be logged, and they will be set to have a red background colour. Try reordering the table, you will notice that reordering only happens when your touches are exactly within the red box.

You can try setting the frame of this view, but the UITableView will just set it’s frame back aftertableView:willDisplayCell:forRowAtIndexPath: is called making our attempts useless, so we need a workaround. This took me a while to figure out, but we need to add the “UITableViewCellReorderControl” to our own custom subview, and then add the custom subview to the cell and set the custom subview’s transform to stretch it over the entire cell.

for(UIView* view in cell.subviews){        if([[[view class] description] isEqualToString:@"UITableViewCellReorderControl"])        {                [view setBackgroundColor:[UIColor redColor]]                UIView* resizedGripView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetMaxX(view.frame), CGRectGetMaxY(view.frame))];                [resizedGripView setBackgroundColor:[UIColor greenColor]];                [resizedGripView addSubview:view];                [cell addSubview:resizedGripView];                [resizedGripView release];        }}

Run the app and now all cell’s are filled with our custom green view with the red grip on the right. Reordering functionality will still work. Now it’s time to figure our what transform this custom view requires for it to fill the entire cell.

for(UIView* view in cell.subviews){        if([[[view class] description] isEqualToString:@"UITableViewCellReorderControl"])        {                [view setBackgroundColor:[UIColor redColor]]                UIView* resizedGripView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetMaxX(view.frame), CGRectGetMaxY(view.frame))];                [resizedGripView setBackgroundColor:[UIColor greenColor]];                [resizedGripView addSubview:view];                [cell addSubview:resizedGripView];                [resizedGripView release]                CGSize sizeDifference = CGSizeMake(resizedGripView.frame.size.width - view.frame.size.width, resizedGripView.frame.size.height - view.frame.size.height);                CGSize transformRatio = CGSizeMake(resizedGripView.frame.size.width / view.frame.size.width, resizedGripView.frame.size.height / view.frame.size.height)                //        Original transform                CGAffineTransform transform = CGAffineTransformIdentity;                 //        Scale custom view so grip will fill entire cell                transform = CGAffineTransformScale(transform, transformRatio.width, transformRatio.height)                //        Move custom view so the grip's top left aligns with the cell's top left                transform = CGAffineTransformTranslate(transform, -sizeDifference.width / 2.0, -sizeDifference.height / 2.0)                [resizedGripView setTransform:transform];        }}

This will make the grip take up the entire cell, you can now reorder from any point on the cell, perfect. Now just some cleanup, remove the red and green colours from the custom view and the “UITableViewCellReorderControl” view. The 3 line grip image will remain. The “UITableViewCellReorderControl” uses a UIImageView subview to display this image, so just loop through the subviews and check the class type, then set any UIImageView‘s image to nil.

for(UIImageView* cellGrip in view.subviews){        if([cellGrip isKindOfClass:[UIImageView class]])                [cellGrip setImage:nil];}

And that is all that’s required, not too much code at all, just a bit of subview hunting and testing to see what works. Here is the complete tableView:willDisplayCell:forRowAtIndexPath: method we wrote

- (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{        //        Grip customization code goes in here...        for(UIView* view in cell.subviews)        {                if([[[view class] description] isEqualToString:@"UITableViewCellReorderControl"])                {                        UIView* resizedGripView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetMaxX(view.frame), CGRectGetMaxY(view.frame))];                        [resizedGripView addSubview:view];                        [cell addSubview:resizedGripView];                        [resizedGripView release]                        CGSize sizeDifference = CGSizeMake(resizedGripView.frame.size.width - view.frame.size.width, resizedGripView.frame.size.height - view.frame.size.height);                        CGSize transformRatio = CGSizeMake(resizedGripView.frame.size.width / view.frame.size.width, resizedGripView.frame.size.height / view.frame.size.height)                        //        Original transform                        CGAffineTransform transform = CGAffineTransformIdentity;                         //        Scale custom view so grip will fill entire cell                        transform = CGAffineTransformScale(transform, transformRatio.width, transformRatio.height)                        //        Move custom view so the grip's top left aligns with the cell's top left                        transform = CGAffineTransformTranslate(transform, -sizeDifference.width / 2.0, -sizeDifference.height / 2.0)                        [resizedGripView setTransform:transform]                        for(UIImageView* cellGrip in view.subviews)                        {                                if([cellGrip isKindOfClass:[UIImageView class]])                                        [cellGrip setImage:nil];                        }                }        }}
And here is the project endpoint.
0 0
原创粉丝点击