strage uitableview cell behavior: view moves inside cell - ios

I am having some strange uitableview behavior- my customs cells have a little extra space around them that I cannot fix. I can also move the cells in that space. I have attached a couple of pictures as my English is not letting me to explain better. Any ideas on what might the issue be? I can post my code for my custom cell but it even happens with admob add cell, so I am not sure it is related to the custom cell.
EDIT: Added code for heights
EDIT2: I changed the scroll view alloc to
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width,self.bounds.size.height)];
And it fixed the moving of the cell. But that white line is still there.
Table View
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// return (self.tableViewHome.bounds.size.height-49-6-self.tableViewHome.tableHeaderView.bounds.size.height-self.tableViewHome.tableFooterView.bounds.size.height-GAD_SIZE_320x50.height)/3;
float height = self.tableViewHome.frame.size.height-self.tableViewHome.tableHeaderView.bounds.size.height-30.0;
if (indexPath.item==5)
{
height=kGADAdSizeBanner.size.height;
}
else
{
if (indexPath.item==1 || indexPath.item==3)
{
height=15.0;
}
else
{
if (indexPath.item==0 || indexPath.item==2 || indexPath.item==4)
{
height=(height-kGADAdSizeBanner.size.height)/3;
}
}
}
NSLog(#"Height:%f",height);
return height;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 0.1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
return 0.1;
}
Custom Cell
-(id) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
{
scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
[scrollView setShowsHorizontalScrollIndicator:NO];
[scrollView setShowsVerticalScrollIndicator:NO];
// NSInteger viewcount= 3;
// for(int i = 0; i< viewcount; i++) {
// CGFloat x = 2 * self.bounds.size.width;
todayView = [HomeTodayView homeTodayView];
todayView.frame = CGRectMake(0, 0,self.bounds.size.width, self.bounds.size.height);
todayView.backgroundColor = [UIColor redColor];
avgView = [HomeAvgView homeAvgView];
avgView.frame = CGRectMake(self.bounds.size.width, 0, self.bounds.size.width, self.bounds.size.height);
// [[HomeTodayView alloc] initWithFrame:
todayView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
avgView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
[scrollView addSubview:todayView];
[scrollView addSubview:avgView];
scrollView.contentSize = CGSizeMake(self.bounds.size.width *2, self.bounds.size.height+100);
scrollView.pagingEnabled = YES;
scrollView.bounces = NO;
[self addSubview:scrollView];
}
return self;
}

Try This:
[table setSeparatorStyle:UITableViewCellSeparatorStyleNone];
NOTE:- table = your tableview name.
If this does not work then please check that your custom cell height and the row height of tableView are same?

Related

Enable bounce/scroll for UICollectionView while no cells

Due to some purposes(like pull to refresh), I need a UICollectionView can bounce or scroll when there is no cells -- means numberOfItemsInSection: return 0
I have my code like this:
...
UICollectionViewFlowLayout *flowLayout =[[UICollectionViewFlowLayout alloc] init];
flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
flowLayout.minimumInteritemSpacing = SPLIT_SPACE;
flowLayout.minimumLineSpacing = SPLIT_SPACE;
targetCollection = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - TABBAR_HEIGHT)
collectionViewLayout:flowLayout];
[targetCollection registerNib:[UINib nibWithNibName:#"DashboardCell" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:#"DashboardCell"];
targetCollection.autoresizingMask = UIViewAutoresizingFlexibleHeight;
targetCollection.backgroundColor = [UIColor colorWithHex:#"#EAEAEA"];
targetCollection.contentInset = UIEdgeInsetsMake(0, 0, 20, 0);
targetCollection.alwaysBounceVertical = YES;
...
#pragma mark - UICollectionViewDataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section;
{
return 0;
}
However, when testing, this empty UICollectionView cannot bounce nor scroll. I suspect it is related to empty cell, but I do need to enable the bounce or scroll when no cell.
This is similar to another of my problem:SVPullToRefresh cannot pull on an empty UICollectionView
Do it like this:
self.collectionView.alwaysBounceVertical = YES;
answer by #VNJ at here
Change this setting in your storyboard:
Swift Solution
collectionView.alwaysBounceVertical = true
You can try this:
collectionView.isScrollEnabled = false
- (void)_edgeInsetsToFit {
UIEdgeInsets edgeInsets = self.collectionView.contentInset;
CGSize contentSize = self.collectionView.contentSize;
CGSize size = self.collectionView.bounds.size;
CGFloat heightOffset = (contentSize.height + edgeInsets.top) - size.height;
if (heightOffset < 0) {
edgeInsets.bottom = size.height - (contentSize.height + edgeInsets.top) + 1;
self.collectionView.contentInset = edgeInsets;
} else {
edgeInsets.bottom = 0;
self.collectionView.contentInset = edgeInsets;
}
}
I called that method after layoutSubviews
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
_STAssetViewController *weakSelf = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[weakSelf _edgeInsetsToFit];
});
}
You can try that way

UIScrollview does not react to any touch?

I am trying to do a simple scroll, but the views do not move after a touch, I am not sure why, the scrollview should handle the gesture, but something might be missing. Would someone know where?
Here is the code : I create a small horizontal scroll view, with some views inside. The views appear well, I am testing it on a device for the touch :
- (void)viewDidLoad {
[super viewDidLoad];
//horizontal scroll view
HorizScroll *ho = [[HorizScroll alloc] initWithFrame:CGRectMake(0, 0, 500, 100)];
for ( int i=0; i<3; i++){
MyView* mv = [[MyView alloc] init];
[ho addSubview:mv];
}
//ho.zoomScale = 0.3f;
[self.view addSubview:ho];
}
#implementation HorizScroll
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
}
return self;
}
-(void)addSubview:(UIView *)view{
[super addSubview:view];
NSUInteger numSubviews = self.subviews.count;
[view setFrame:CGRectMake(CGRectGetWidth(view.bounds)*(numSubviews),
0,
CGRectGetWidth(view.bounds),
CGRectGetHeight(view.bounds) )];
[self setContentSize:CGSizeMake(CGRectGetWidth(view.bounds)*(numSubviews),
CGRectGetHeight(view.bounds) )];
}
#implementation MyView
-(int)getRandomNumberBetween:(int)from to:(int)pto {
return (int)(from + arc4random() % (pto-from+1));
}
-(instancetype)init{
if ( self = [super init] ){
CGFloat red = [self getRandomNumberBetween:1 to:255];
self.backgroundColor = [UIColor colorWithRed:red/256.0
green:[self getRandomNumberBetween:1 to:255]/256.0
blue:[self getRandomNumberBetween:1 to:255]/256.0
alpha:1.0];
}
return self;
}
-(instancetype)initWithFrame:(CGRect)frame{
if ( self = [super initWithFrame:frame] ){
self.frame = CGRectMake(counterX, 0, 100, 100);
counterX += 50;
}
return self;
}
You need to set contentSize of scrollview to be larger than its frame size. so add this line after [self.view addSubview:ho].
ho.contentSize = CGSizeMake(501.f, 100.f);
or before [self.view addSubview:ho] and comment out the line:
[self setContentSize:CGSizeMake(CGRectGetWidth(view.bounds)*(numSubviews),
CGRectGetHeight(view.bounds))];
which is not necessary since you can set it after all subviews are added.

Adjusting code to include Lazy loading - scrollview and images

Im trying to refactor my code for better memory management and performance. I have an array of 12 images, but I want to load them as needed, not all at the same time. So maybe the current image -1, the current image and the current image +1. I viewed some of the answers on SO but found them unclear. I felt it would be clearer if I posted my code for reference.
//scroll view set up
- (void)scrollViewSetUp
{
self.scrollview.delegate = self;
for (int i = 0; i < _images.count; i++)
{
CGRect frame;
frame.origin.x = self.scrollview.frame.size.width * i;
frame.size = self.scrollview.frame.size;
self.scrollview.pagingEnabled = YES;
UIImageView *subview = [[UIImageView alloc] initWithFrame:frame];
subview.image = [UIImage imageNamed:[_images objectAtIndex:i]];
[self.scrollview addSubview:subview];
}
self.scrollview.contentSize = CGSizeMake(self.scrollview.frame.size.width * _images.count, self.scrollview.frame.size.height);
self.automaticallyAdjustsScrollViewInsets = NO;
//page control ie .... at bottom of
self.pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(100.0,0.0,100.0,40.0)];
[self.pageControl setNumberOfPages:_images.count];
[self.pageControl setCurrentPage:0];
self.pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
self.pageControl.currentPageIndicatorTintColor = [UIColor whiteColor];
[self.pageControl setBackgroundColor:[UIColor clearColor]];
[self.viewForPageControl addSubview:self.pageControl];
[self.viewForPageControl setBackgroundColor:[UIColor clearColor]];
}
#pragma mark - UIScrollView Delegate
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
int newOffset = scrollView.contentOffset.x;
int newPage = (int)(newOffset/(scrollView.frame.size.width));
[_pageControl setCurrentPage:newPage];
}
Any advice or direction is greatly appreciated.
As per Gman's request I reposted my comment.
This tutorial will help you:
http://www.raywenderlich.com/10518/how-to-use-uiscrollview-to-scroll-and-zoom-content
You could try to reuse your UIImageView as they go offscreen... but you'll be just trying to redo what UITableview already does. UITableView with a custom UITableViewCell would take care of notifying you when new cells comes visible and dequeuing the ones that are offscreen.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"yourCustomImageCell";
//look if there are cells that could be reused
CustomImageCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) { //if not, create a new one
cell = [[CustomImageCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
//Set your image here
return cell;
}
Not sure if this is the best way of doing it, but it's an option.
You can set the tag property on your UIImageView to correspond to your index in your loop when setting the scrollView.
Then in your scrollViewDidEndDecelerating method:
for (int i = 0; i < _salonImages.count; i++)
{
if(i == (newPage-1))
{
UIImageView *imgView = (UIImageView*)[self.scrollView viewWithTag:newPage-1];
imgView.image = [_images objectAtIndex:newPage-1];
}
else if(i == newPage)
{
UIImageView *imgView = (UIImageView*)[self.scrollView viewWithTag:newPage];
imgView.image = [_images objectAtIndex:newPage];
}
else if(i == (newPage + 1 ))
{
UIImageView *imgView = (UIImageView*)[self.scrollView viewWithTag:newPage+1];
imgView.image = [_images objectAtIndex:newPage+1];
}
else
{
UIImageView *imgView = (UIImageView*)[self.scrollView viewWithTag:i];
imgView.image = nil;
}
}

UITableView contentSize wrong when using UISearchBar

UITableView is reporting a bigger contentSize than expected when using a UISearchBar. With zero cells, the expected content height would be zero. Instead, the following code outputs 612 in iPhone 4-inch running iOS 7.
#implementation HPViewController {
UITableView *_tableView;
UISearchBar *_searchBar;
UISearchDisplayController *_searchController;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
_tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:_tableView];
_searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
_searchController = [[UISearchDisplayController alloc] initWithSearchBar:_searchBar contentsController:self];
_searchController.delegate = self;
_searchController.searchResultsDataSource = self;
_tableView.tableHeaderView = _searchBar;
}
- (void)viewDidLayoutSubviews
{
CGSize contentSize = _tableView.contentSize;
NSLog(#"%f", contentSize.height); // 612.000000
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 0; }
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { return nil; };
#end
Commenting the line that sets the header view makes the code output 0, as expected.
Also, if I assign an empty UIView as the header, the contentSize will be correct and match the height of the header. The problem only happens with UISearchBar.
Is there any way around this? Am I doing something wrong?
Placing the UISearchBar inside a container UIView mostly fixes the problem.
- (void)viewDidLoad
{
[super viewDidLoad];
_tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
_tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:_tableView];
UIView *searchBarContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
_searchBar = [[UISearchBar alloc] initWithFrame:searchBarContainer.bounds];
[searchBarContainer addSubview:_searchBar];
_searchController = [[UISearchDisplayController alloc] initWithSearchBar:_searchBar contentsController:self];
_searchController.delegate = self;
_searchController.searchResultsDataSource = self;
_tableView.tableHeaderView = searchBarContainer;
}
Unfortunately the UISearchBar glitches in some scenarios that I couldn't isolate yet. I opted to calculate the contentSize manually by adding the height of all cells.
Starting from iOS11, UITableView uses estimate row/header/footer height to calculate initial contentSize by default. In fact, if you tap on the search bar and dismiss the keyboard, content size will have the correct value.
To fix this behavior, set estimate row, header and footer height to 0 in IB instead of Automatic:
or just do it programmatically:
self.tableView.estimatedRowHeight = 0;
self.tableView.estimatedSectionHeaderHeight = 0;
self.tableView.estimatedSectionFooterHeight = 0;
Add this delegate method
-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
return [[UIView alloc] initWithFrame:CGRectZero];
}
Maybe your view for footer is groing up because there is no cells to show.

Subclassing UITableViewCell causes text and image to shift when loaded

I have created a subclass of UITableViewCell because I want to explicitly set the imageView frame size, regardless of the size of the images I actually give it.
That being said, when my tableView loads, everything seems to shift after a split second. The image gets slightly larger, and the titleLabel and detailLabel both shift over closer to the image. Have I done something wrong in my subclass?
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Selected View
self.selectedBackgroundView = [[UIView alloc] initWithFrame:self.frame];
self.selectedBackgroundView.backgroundColor = RGB(233, 233, 233);
// Text Label
self.textLabel.textColor = [UIColor darkGrayColor];
self.textLabel.opaque = YES;
self.textLabel.highlightedTextColor = self.textLabel.textColor;
// Detail
self.detailTextLabel.font = [UIFont systemFontOfSize:12.0];
self.detailTextLabel.numberOfLines = 3;
self.detailTextLabel.opaque = YES;
self.detailTextLabel.highlightedTextColor = self.detailTextLabel.textColor;
// Cell
self.opaque = YES;
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)layoutSubviews {
[super layoutSubviews];
float desiredWidth = 70;
float desiredHeight = 70;
float leftMargin = 5;
float topMargin = 5;
float w=self.imageView.frame.size.width;
self.imageView.contentMode = UIViewContentModeScaleAspectFill;
self.imageView.clipsToBounds = YES;
if (w>desiredWidth) {
float widthSub = w - desiredWidth;
self.imageView.frame = CGRectMake(leftMargin,topMargin,desiredWidth,desiredHeight);
self.textLabel.frame = CGRectMake(self.textLabel.frame.origin.x-widthSub,self.textLabel.frame.origin.y,self.textLabel.frame.size.width+widthSub,self.textLabel.frame.size.height);
self.detailTextLabel.frame = CGRectMake(self.detailTextLabel.frame.origin.x-widthSub,self.detailTextLabel.frame.origin.y,self.detailTextLabel.frame.size.width+widthSub,self.detailTextLabel.frame.size.height);
}
}
I see you are doing
self.selectedBackgroundView = [[UIView alloc] initWithFrame:self.frame];
I really think it should be
self.selectedBackgroundView = [[UIView alloc] initWithFrame:self.bounds];
because self.selectedBackgroundView is positioned based on parent view coordinate system

Resources