CollectionView horizontal scroll not working in ios 7 but it's working fine in ios 8 and 9. Is there any solution for this ?
The Code is here:
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
layout.itemSize = CGSizeMake(330, 100);
collection = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0, 50.0, 350, 100) collectionViewLayout:layout];
collection.delegate = self;
collection.dataSource = self;
collection.backgroundColor = [UIColor greenColor];
collection.pagingEnabled = YES;
[collection registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"Cell"];
[self.view addSubview:collection];
It now fits my needs, and could be useful for someone else, so here is my code:
I have tested In iOS7-8-9. Below example is for Default iPad. You Just need to change target settings and O.S Version.
https://github.com/philippeauriach/fullyhorizontalcollectionview
Please download it & let us know ur comments. Happy Coding!
If you want to add collection view onto the View then use below code. Below code into i have created CL View programmatically and It's also working correctly with Autolayout and iOS 7-8-9. Please implement below code and let us know ur comments.
.H File
#interface HorizontalCollectionViewController : UIViewController<UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>{
NSIndexPath *visibleIndexPath;
}
#property (nonatomic, assign) NSInteger selectedCell;
#property (strong, nonatomic) IBOutlet UICollectionView *horizonCLView;
.M File
#import "HorizontalCollectionViewController.h"
static NSString * const CellIdentifier = #“horizonCell";
#interface HorizontalCollectionViewController ()
#end
#implementation HorizontalCollectionViewController
#synthesize horizonCLView;
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"view frame : %#",NSStringFromCGRect(self.view.frame));
[self.view layoutIfNeeded];
[self.view setNeedsLayout];
[self viewDidLayoutSubviews];
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
layout.itemSize = self.view.frame.size;
[layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
[layout setMinimumInteritemSpacing:0.f];
[layout setMinimumLineSpacing:0.f];
layout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
horizonCLView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
horizonCLView.dataSource = self;
horizonCLView.delegate = self;
horizonCLView.backgroundColor = [UIColor lightGrayColor];
horizonCLView.scrollEnabled = YES;
[horizonCLView setBounces:NO];
[horizonCLView setUserInteractionEnabled:YES];
[horizonCLView setPagingEnabled:YES];
[horizonCLView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:CellIdentifier];
[self.view addSubview:horizonCLView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
-(void)viewWillAppear:(BOOL)animated{
//Select Current Image For Sare In Social Media
// currentImageIndex = selectedCell;
[horizonCLView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:selectedCell inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
CGRect visibleRect = (CGRect){.origin = self.horizonCLView.contentOffset, .size = self.horizonCLView.bounds.size};
CGPoint visiblePoint = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect));
visibleIndexPath = [self.horizonCLView indexPathForItemAtPoint:visiblePoint];
// NSLog(#"visibleIndexPath.row in View will appear %ld",(long)visibleIndexPath.row);
//SelectedCell is a selected image from gallary view
NSLog(#"selectedCell in View will appear: %ld",(long)selectedCell);
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return [dataAry count];
}
#pragma Here we set the frame of horizontal scrll view
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
// expand cell to fill the entire view
return collectionView.frame.size;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
self.title = [[self.dataAry objectAtIndex:indexPath.row] valueForKey:#“dataAryName"];
//imageVI.image = nil;
imageVI = (UIImageView *)[cell.contentView viewWithTag:100];
if (!imageVI){
imageVI = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,self.view.bounds.size.width,self.view.bounds.size.height)];
imageVI.contentMode = UIViewContentModeScaleAspectFill;
imageVI.tag = 100;
imageVI.clipsToBounds = YES;
[cell.contentView addSubview:imageVI];
}
dispatch_async(dispatch_get_main_queue(), ^{
[asSetLib assetForURL:[NSURL URLWithString:[[self.dataAry objectAtIndex:indexPath.row] valueForKey:#"dataAryName"]] resultBlock:^(ALAsset *asset) {
// imageVI.image = [UIImage imageWithCGImage:asset.defaultRepresentation.fullScreenImage];
imageVI.image = [UIImage imageWithCGImage:asset.defaultRepresentation.fullResolutionImage];
NSLog(#"Preview view into album loaded successfully!");
} failureBlock:^(NSError *error) {
NSLog(#"An error occurred while loading image: %#", error.description);
}];
});
return cell;
}
Sudha, I think this issues in your code not an iOS7 issues.
Here, I have review two bug in ur code.
1)In this line you have give static width of collection view,
collection = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0, 50.0, 350, 100) collectionViewLayout:layout];
Instead Of it will be goes look like,
collection = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0, 50.0, self.view.bounds.size.width, 100) collectionViewLayout:layout];
Make sure your collection view width size always go with according to your view size.
2)Make sure, Your layout item size width higher then collection view width frame. Otherwise Scrolling was not effected.
layout.itemSize = CGSizeMake(self.view.bounds.size.width+10, 100);
3) Carefully use,
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
delegate method of collectionview layout size method.
4)Finally your code look like,
- (void)viewDidLoad {
[super viewDidLoad];
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
layout.itemSize = CGSizeMake(self.view.bounds.size.width+10, 100);
[layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
collection = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0, 50.0, self.view.bounds.size.width, 100) collectionViewLayout:layout];
collection.delegate = self;
collection.dataSource = self;
collection.backgroundColor = [UIColor greenColor];
collection.pagingEnabled = YES;
collection.scrollEnabled = YES;
collection.userInteractionEnabled = YES;
[collection registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"Cell"];
[self.view addSubview:collection];
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return 1;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
return cell;
}
Happy Coding!
I've used a line of code after adding collectionView on view that its working fine in ios 7 also.
add this code after [self addSubview:self.collectionView];
here the code:
[self performSelector:#selector(update) withObject:nil afterDelay:1];
(void)update {
[self.collectionView setContentOffset:CGPointMake(1, 0)];
}
Related
I have a UICollectionView in a custom UITableViewCell, only UIImageView in the UICollectionView. I use SDWebImage to load image.What I want is after loading the image, both UICollectionView and it's contentView(UITableViewCell) update themselves' height to show all the image. For example, if I have three images in UICollectionView, I hope the collectionview's height equals to all three images' height summation.
Here is some code:
TableView:
- (void)createPostDetailUI{
_postDetailTableView = [UITableView new];
_postDetailTableView.delegate = self;
_postDetailTableView.dataSource = self;
_postDetailTableView.estimatedRowHeight = 180;
_postDetailTableView.tableFooterView = [UIView new];
[_postDetailTableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
_postDetailTableView.rowHeight = UITableViewAutomaticDimension;
[self makeConstraints];
}
- (void)makeConstraints{
[_postDetailTableView mas_makeConstraints:^(MASConstraintMaker *make) {
UIEdgeInsets padding = UIEdgeInsetsMake(0, 0, 50, 0);
make.edges.equalTo(self.view).insets(padding);
}];
}
- (void)requestPostData{
//some request code
[_commentsArray addObjectsFromArray:[PostCommentModel arrayWithResponseObject:responseObject][0]];
[_postDetailTableView reloadData];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return _commentsArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
PostDetailHeaderTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"PostDetailHeaderTableViewCell" forIndexPath:indexPath];
cell = [[PostDetailHeaderTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"PostDetailHeaderTableViewCell"];
[cell updateCellWithModel:_postModel];
return cell;
}
UITableViewCell(UICollectionView inside it):
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
//some other views
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
layout.minimumLineSpacing = 4.0;
layout.estimatedItemSize = CGSizeMake(300, 300);
_postImageCollectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
_postImageCollectionView.backgroundColor = [UIColor clearColor];
_postImageCollectionView.showsHorizontalScrollIndicator = NO;
_postImageCollectionView.autoresizesSubviews = YES;
[_postImageCollectionView registerClass:[PostDetailImageCollectionViewCell class] forCellWithReuseIdentifier:#"PostDetailImageCollectionViewCell"];
_postImageCollectionView.delegate = self;
_postImageCollectionView.dataSource = self;
[self.contentView addSubview:_postImageCollectionView];
[self makeConstraints];
}
return self;
}
- (void)makeConstraints{
//some other views' autolayout code
[_postImageCollectionView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(_postContentLabel);
make.right.equalTo(_postContentLabel);
make.top.equalTo(_postContentLabel.mas_bottom).offset(14);
make.height.greaterThanOrEqualTo(#20);
make.bottom.equalTo(self.contentView).offset(-16);
}];
}
- (void)updateCellWithModel:(PostsModel *)model{
_imageArray = [model getImageList];
[_postImageCollectionView reloadData];
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return _imageArray.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
PostDetailImageCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"PostDetailImageCollectionViewCell" forIndexPath:indexPath];
NSString *cellImageURL = _imageArray[indexPath.row];
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:cellImageURL] placeholderImage:[UIImage imageNamed:#"icon_default"]];
return cell;
}
UICollectionViewCell:
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
_imageView = [UIImageView new];
_imageView.frame = self.contentView.frame;
_imageView.contentMode = UIViewContentModeScaleAspectFit;
[self.contentView addSubview:_imageView];
}
return self;
}
I use auto layout and use masonry to manage it. But whatever I try to fix it, it just show me 20pt height.
ps:How to make CollectionViewCell frame fit image frame
Try this to calculate height
CGheight height= [self.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height+2;
add this in ur custom cell and call this from collectionview delegate method
I created a UIView with a UICollectionView, and that UIView is added on a UIViewController. UIViewController using the delegate (photoDidTapped) of that UIView to determine is something was clicked/tapped. First row, is okay, means whole cell area is tappable. Second row, horizontal half of that is clickable. 3rd row, almost 10% horizontal of the cell is clickable and so on.
Code:
- (UICollectionView *)collectionView
{
if (!_collectionView) {
UICollectionViewFlowLayout *flowLayout=[[UICollectionViewFlowLayout alloc] init];
flowLayout.itemSize = CGSizeMake(THUMB_DIMENSION, THUMB_DIMENSION);
[flowLayout setMinimumInteritemSpacing:0.0f];
[flowLayout setMinimumLineSpacing:PHOTO_MARGIN];
_collectionView = [[UICollectionView alloc] initWithFrame:self.frame collectionViewLayout:flowLayout];
_collectionView.frame = CGRectMake(0, 0, SCREEN_WIDTH, self.frame.size.height);
_collectionView.backgroundColor = [UIColor clearColor];
_collectionView.delegate = self;
_collectionView.dataSource = self;
_collectionView.allowsSelection = YES;
_collectionView.alwaysBounceVertical = YES;
_collectionView.scrollEnabled = NO;
[_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"Cell"];
}
return _collectionView;
}
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section {
return (_photos.count > 9 ? 9 : _photos.count);
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath; {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, cell.frame.size.width, cell.frame.size.height)];
imgView.clipsToBounds = YES;
imgView.backgroundColor = RGB(250, 250, 250);
if (_photos.count) {
PhotoDM *photo = [_photos objectAtIndex:indexPath.row];
[imgView setImageWithURL:[NSURL URLWithString:photo.largeLink]
placeholderImage:[UIImage imageNamed:#"placeholder"]];
}
[cell addSubview:imgView];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"tapped: %ld", (long)indexPath.row);
if([delegate respondsToSelector:#selector(photoDidTapped:)])
[delegate performSelector:#selector(photoDidTapped:) withObject:[[NSNumber alloc] initWithInteger:indexPath.row] ];
}
Your code contains 2 problems.
1. If you create a subview, you should use self.bounds.
2. The view can be resized, after UICollectionView has been added. It means that you should configure autoresizingMask or NSLayoutConstrans. (UICollectionView can be out of view's bounds).
To debug this problem, you can create different background colors for the view, the collectionView, the viewController's view.
I have a UICollectionView that is using the Flow Layout. At this point I'm not really doing anything special. I'm just programmatically adding the view and the UICollectionViewCell.
When you touch a cell it is registering the touch event for the cell that is located above it. So if you touch a cell on row 2 the the cell above is the one that actually registers the touch.
Here is the code that I have setting things up.
#interface KFYSearch() <UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, UISearchBarDelegate>
#property(nonatomic, strong)UISearchBar *searchBar;
#property(nonatomic, strong)UICollectionView *collectionView;
#property(nonatomic, strong)NSArray *collectionData;
#end
#implementation KFYSearch
-(id)initWithView:(UIView*)view
{
self = [super init];
if(self)
self.view = view;
return self;
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if(_searchBar == nil)
{
self.view.frame = CGRectMake(20, 20, self.view.superview.frame.size.width - 40, self.view.superview.frame.size.height - 40);
[self.view setBackgroundColor:[UIColor whiteColor]];
[self createChildViews];
}
}
-(void)createChildViews
{
_searchBar = [[UISearchBar alloc] initWithFrame: CGRectMake(5, 5, self.view.frame.size.width - 10, 30)];
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc]init];
_collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(_searchBar.frame.origin.x, _searchBar.frame.origin.y + (_searchBar.frame.size.height + 2), _searchBar.frame.size.width, self.view.frame.size.height - ((_searchBar.frame.origin.y + _searchBar.frame.size.height) + 10)) collectionViewLayout:flowLayout];
_collectionView.dataSource = self;
_collectionView.delegate = self;
[_collectionView registerClass:[KFYKlickableCell class] forCellWithReuseIdentifier:#"Cell"];
[_collectionView setBackgroundColor:[UIColor whiteColor]];
[self.view addSubview:_searchBar];
[self.view addSubview:_collectionView];
[self getData];
}
-(void)getData
{
KFYGetKlickablesAction *getKlickablesAction = [[KFYGetKlickablesAction alloc]init];
_collectionData = [getKlickablesAction mockData];
[_collectionView reloadData];
}
#pragma UICollectionView Delegate stuff;
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return _collectionData.count;
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
KFYKlickableCell *cell= [_collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
[cell setBackgroundColor:[UIColor redColor]];
KFYKlickableVO *vo = [_collectionData objectAtIndex:indexPath.row];
[cell renderKlickable:vo];
return (UICollectionViewCell*)cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(60, 60);
}
-(UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
return UIEdgeInsetsMake(5, 5, 5, 5);
}
-(void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath
{
KFYKlickableVO *vo = [_collectionData objectAtIndex:indexPath.row];
NSLog(vo.tag);
}
#pragma UITextField Delegate stuff
-(void)textFieldDidBeginEditing:(UITextField *)textField {
//Keyboard becomes visible
self.view.frame = CGRectMake(self.view.frame.origin.x,
self.view.frame.origin.y,
self.view.frame.size.width,
self.view.frame.size.height - 215 + 50); //resize
}
-(void)textFieldDidEndEditing:(UITextField *)textField {
//keyboard will hide
self.view.frame = CGRectMake(self.view.frame.origin.x,
self.view.frame.origin.y,
self.view.frame.size.width,
self.view.frame.size.height + 215 - 50); //resize
}
#end
I have written a subclass of UITableViewCell to allow horizontal swipe to give some actions to users. Here is what I am doing:
Create a scrollView
Create a buttonView and add in scrollView.
Create a UIButton and add all cell controls as subview to it. Add in scroll view.
Add scrollView to cell contentView.
For #3 I am setting the highlighted image to give a feel of user tap like in normal cell.
The issue is when my table view is loaded on iOS 6 with 6 cells and user tap on any of the cell, cell gets highlighted properly and the details are shown properly for the tapped cell. But if user scrolls up and first cell is re-used and user tap on the top cell (which is second row), cell next to it gets highlighted. If user scrolls up and purge 2 cells and tap on the top cell, cell 2 cells down it gets highlighted. Although tapped cell shows the data of the correct cell.
Any clue?
- (id)initWithStyle:(UITableViewCellStyle)iStyle reuseIdentifier:(NSString *)iReuseIdentifier andMenuButtonDetails:(NSArray *)iMenuButtonDetails {
if ((self = [super initWithStyle:iStyle reuseIdentifier:iReuseIdentifier])) {
self.catchWidth = kMenuButtonWidth * [iMenuButtonDetails count];
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(kScreenOrigin, kScreenOrigin, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds))];
self.scrollView.contentSize = CGSizeMake(CGRectGetWidth(self.bounds) + self.catchWidth, CGRectGetHeight(self.bounds));
self.scrollView.delegate = self;
self.scrollView.showsHorizontalScrollIndicator = NO;
self.scrollView.scrollEnabled = YES;
[self.contentView addSubview:self.scrollView];
self.scrollViewButtonView = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.bounds) - self.catchWidth, kScreenOrigin, self.catchWidth, CGRectGetHeight(self.bounds))];
[self.scrollView addSubview:self.scrollViewButtonView];
if ([iMenuButtonDetails count]) {
// Adding menu buttons to the cell.
CGFloat anXOffset = kScreenOrigin;
for (NSDictionary *aMenuButton in iMenuButtonDetails) {
if ([aMenuButton containsObjectForKey:kTitleKey]) {
UIButton *aButton = [[UIButton alloc] initWithFrame:CGRectMake(anXOffset, kScreenOrigin, kMenuButtonWidth, kCellHeight64)];
[aButton addTarget:self action:#selector(buttonSelected:) forControlEvents:UIControlEventTouchUpInside];
if ([aMenuButton containsObjectForKey:kButtonTagKey])
aButton.tag = [[aMenuButton stringForKey:kButtonTagKey] intValue];
aButton.titleEdgeInsets = UIEdgeInsetsMake(kScreenOrigin, 2.0, kScreenOrigin, 2.0);
aButton.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
[aButton.titleLabel setTextAlignment:NSTextAlignmentCenter];
[aButton setTitle:[aMenuButton stringForKey:kTitleKey] forState:UIControlStateNormal];
[aButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
if ([aMenuButton objectForKey:kButtonColorKey]) {
aButton.backgroundColor = [aMenuButton objectForKey:kButtonColorKey];
}
[self.scrollViewButtonView addSubview:aButton];
anXOffset += kMenuButtonWidth;
}
}
}
self.scrollViewContentView = [UIButton buttonWithType:UIButtonTypeCustom];
self.scrollViewContentView.frame = CGRectMake(kScreenOrigin, kScreenOrigin, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds));
if (![Utilities isIOS7orAbove]) {
[self.scrollViewContentView addTarget:self action:#selector(cellHighlighted) forControlEvents:UIControlEventTouchDown];
[self.scrollViewContentView addTarget:self action:#selector(cellCancelHighlight) forControlEvents:UIControlEventTouchDragExit];
}
[self.scrollViewContentView addTarget:self action:#selector(selectCell:) forControlEvents:UIControlEventTouchUpInside];
self.scrollViewContentView.backgroundColor = [UIColor whiteColor];
UIImage *aBGHighlightedImage = nil;
if ([Utilities isIOS7orAbove]) {
aBGHighlightedImage = [UIImage imageNamed:kCellHighlightedImageIOS7];
} else {
aBGHighlightedImage = [UIImage imageNamed:kCellHighlightedImageIOS6];
}
[self.scrollViewContentView setBackgroundImage:[aBGHighlightedImage stretchableImageWithLeftCapWidth:11.0f topCapHeight:0] forState:UIControlStateHighlighted];
[self.scrollView addSubview:self.scrollViewContentView];
[self.scrollViewContentView addSubview:self.imageView];
[self.scrollViewContentView addSubview:self.textLabel];
[self.scrollViewContentView addSubview:self.detailTextLabel];
}
- (void)prepareForReuse {
[super prepareForReuse];
self.scrollViewContentView.enabled = YES;
[self.scrollView setContentOffset:CGPointZero animated:NO];
}
- (UITableViewCell *)tableView:(UITableView *)iTableView cellForRowAtIndexPath:(NSIndexPath *)iIndexPath {
MyTableViewCell *aCell = (MyTableViewCell *)[iTableView dequeueReusableCellWithIdentifier:#"CellIdentifier"];
if (!aCell) {
aCell = [[MyTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"CellIdentifier" andMenuButtonDetails:aMenuButtons];
}
// Set data on cell now
return aCell
}
Let me know if there is something I'm missing here, but it seems like you're adding a ton of complexity to your class for no reason. Are you familiar with UICollectionView?
Here's an example implementation (which scrolls horizontally):
#interface asdf () <UICollectionViewDataSource, UICollectionViewDelegate>
#property (strong, nonatomic) UICollectionView *collectionView;
#end
#implementation asdf
- (id)init
{
self = [super init];
if (self)
{
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:self.collectionViewLayout];
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
[self.view addSubview:self.collectionView];
NSString *className = NSStringFromClass([UICollectionViewCell class]);
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:className];
}
return self;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.collectionView.frame = self.view.bounds;
}
- (UICollectionViewLayout *)collectionViewLayout
{
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.minimumInteritemSpacing = 0;
layout.minimumLineSpacing = 0;
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
return layout;
}
#pragma mark - UICollectionView
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 5;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
NSString *className = NSStringFromClass([UICollectionViewCell class]);
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:className forIndexPath:indexPath];
// This is for dequeuing
NSInteger tag = 12324;
UIView *view = [cell viewWithTag:tag];
if (view)
[view removeFromSuperview];
view = [[UIView alloc] initWithFrame:cell.bounds];
view.tag = tag;
// Add all of your subviews to the view property
[cell addSubview:view];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(collectionView.bounds.size.width, 50);
}
#end
I wrote this quickly as a sample, so it's not tailored specifically to what you're building, but this should give you a nice idea of how simple it is to implement a UICollectionView.
This answer may come across as random for what you're asking, but when possible, you should always try to use what Apple provides over what you would spend precious hours re-inventing the wheel w/ & likely experience random nuances like yours.
I'm using a ViewController in which I add a UICollectionView this way:
UICollectionViewFlowLayout *collectionViewFlowLayout = [[UICollectionViewFlowLayout alloc] init];
[collectionViewFlowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
[collectionViewFlowLayout setMinimumInteritemSpacing:2];
[collectionViewFlowLayout setMinimumLineSpacing:4];
[collectionViewFlowLayout setHeaderReferenceSize:CGSizeMake(320, 30)];
CGRect collectionViewFrame = self.view.bounds;
self.collectionView = [[UICollectionView alloc] initWithFrame:collectionViewFrame collectionViewLayout:collectionViewFlowLayout];
self.collectionView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
[self.collectionView registerClass:[MyCollectionViewCell class] forCellWithReuseIdentifier:myCellIdentifier];
[self.view addSubview:self.collectionView];
And this is how I'm initializing my custom cell object (I made sure the frame for each cell filled the whole width of the screen, so that the cells would be rendered one after another vertically in the UICollectionView):
CGSize mySize = CGSizeMake(320, 158);
self.myTitle = [[UILabel alloc ] initWithFrame:CGRectMake(0, 0, mySize.width, mySize.height)];
[self.myTitle setTextColor:[UIColor whiteColor]];
[self.myTitle setBackgroundColor:[UIColor greenColor]];
[self.myTitle setTextAlignment:NSTextAlignmentLeft];
[self.myTitle setNumberOfLines:1];
[self.myTitle setText:#"My Title"];
[self addSubview:self.myTitle];
This is how I initialize the frame of the cell in initWithNibName:
CGSize mySize = CGSizeMake(320, 158);
self = [super initWithFrame:CGRectMake(0, 0, mySize.width, mySize.height)];
And here's my cellForItemAtIndexPath code:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = (UICollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:myCellIdentifier forIndexPath:indexPath];
return cell;
}
Now I have four of these cells, yet they are overlapping. What am I doing wrong? Thanks!
Implement UICollectionViewFlowLayout delegate call:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(320, 158);
}
Or since all the sizes are constant just specify the size in your Flow layout like so:
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc]init];
flowLayout.itemSize = CGSizeMake(320, 158);
in numberOfSectionsInCollectionView: method use
[self.collectionView.collectionViewLayout invalidateLayout];
I Hope It will work!