UIRefreshControl not centred with contentInset set - ios

I have a refresh control added to a collection view. Everything working, but when I set the collectionView.contentInset = UIEdgeInsetsMake(0, 20, 20, 20) the width of the refresh control stays the same but is shifted 20px, so is not centred in the view. The control should be reduced by 40px for it to be correct.
self.collectionView = [[UICollectionView alloc] initWithFrame:rect collectionViewLayout:flowLayout];
self.collectionView.contentInset = UIEdgeInsetsMake(0, 20, 20, 20)
UIRefreshControl* pullDownRefresh = [[UIRefreshControl alloc] init];
[pullDownRefresh addTarget:self action:#selector(refresh:) forControlEvents:UIControlEventValueChanged];
[self.collectionView addSubview:pullDownRefresh];
I have tried setting the width manually after adding the view (also in viewWillLayoutSubviews), and playing with autoresizingMask to no avail.
Any ideas? I guess I will need to resort to putting it in a container view...but shouldn't need to!

OK, fixed the problem by not setting collectionView.contentInset. Instead I set on the flowLayout
i.e.
flowLayout.sectionInset = UIEdgeInsetsMake(0, 20, 20, 20);

The accepted answer didn't fit my needs, because I had a complicated collectionView with multiple types of cells and each had specific insets for sections, so I didn't want to dive in and add complexity with this solution.
What worked for me was pretty easy. Add the UIRefreshControl to the collectionView's backgroundView instead:
collectionView.backgroundView = viewModel.refreshControl
And when finishing the refresh, just do this:
DispatchQueue.main.async {
self.viewModel.refreshControl?.endRefreshing()
}

Related

None option not included in simulated metrics

I've been trying to load my headerView.xib file onto my BNRItemViewControlelr file which already has its on view.
I am just adding my headerView file onto the BNRItemViewController view. However when I look in the simulated metrics to try and to edit the size of the view there ins't a none option, instead just a freeform which still doesn't change the actual view at runtime. Is there a way I could change it?
(I can't currently post the pictures because I need 10 reputation points)
Just set the frame directly in the code, like this:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"UITableViewCell"];
// Adding top margin to the header view
UIEdgeInsets inset = UIEdgeInsetsMake(20, 0, 0, 0);
self.tableView.contentInset = inset;
UIView *header = self.headerView;
// making the frame for the header view
header.frame = CGRectMake(0, 0, 400, 57);
[self.tableView setTableHeaderView:header];
}
I actually found the answer in this stackoverflow thread: Adding constraint to a UITableVIew headerview
to add top margin: Top margin on UITableViewController
we are using UIEdgeInsets

iOS: Table view, allow scrolling "further down" than the end

Sorry the question sounds a bit confusing. I have two buttons overlapping my table view at the bottom, so if the table view scrolls "normal" the last row is partially hidden by these buttons. That's why I want to allow scrolling the table like the height of one row further down, so the last row is on top of these two buttons. How can I achieve this?
Adjust the content insets of the table view.
For instance, if your buttons are 50 points in height and your table's frame is the full window, you could set your table to snap to the top of your buttons like this:
tableView.contentInset = UIEdgeInsetsMake(0, 0, 50, 0);
Note: In iOS 7+ view controllers have a property automaticallyAdjustsScrollViewInsets that is set to YES by default. When this property is set to YES, the contentInsets you set manually may be overridden. Assuming you have a nav bar of some kind that you want to scroll under, you can set your top edge inset to the length of the topLayoutGuide.
Your final solution (put this in viewDidLoad):
self.automaticallyAdjustsScrollViewInsets = NO;
tableView.contentInset = UIEdgeInsetsMake(self.topLayoutGuide.length, 0, 50, 0);
As pointed out by others, deprecations have made this solution impossible, and if we use a section footer, this will display at the inset all the time. A much simpler solution would be to add a tableFooterView to allow the bottom cells to scroll past the buttons. Like so:
let bottomView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 83))
bottomView.backgroundColor = .clear
tableView.tableFooterView = bottomView
This will make it so the contents shift up.
If you want them to shift down you can change the insets accordingly.
func shiftScrollingUp() {
yourScrollView.contentInsetAdjustmentBehavior = .never
yourScrollView.contentInset = UIEdgeInsetsMake(0, 0, 150, 0)
}
AutomaticallyAdjustsScrollViewInsets is deprecated in ios 11.

Some troubles with UIScrollView

I've just started working with XCode 5.1 and iOS 7.1.
Im having some problems with PartialViews containing a scrollview. I have this ). I marked in red the space the scrollview should occupy but its taking more space vertically and horizontally. The viewcontroller and view are defined in the storyboard as freeform of 500x500 and the scrollview is defined like:
scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, rowHeight*[lstMatches count])];
scroll.contentSize = CGSizeMake(self.view.frame.size.width, rowHeight*[lstMatches count]);
//.....more elements here, added as subviews of scrollview
[self.view addSubview:scroll];
The problem is the next:
1) The scrollview is wider than its container so I can't click over right buttons. I tried changing the width of the viewcontroller and view to 800 (max width is about 750), but i cant click them.
Thanks for your help
try:
scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height])];
scroll.contentSize = CGSizeMake(5000, rowHeight*[lstMatches count]);
[self.view addSubview:scroll];
PS: Change the contentSize.width of 5000 to something that suits your needs

UITableView headerView scroll offset

I'm facing a problem with UITableView and it's property tableHeaderView.
I want to have the tableHeaderView to behave like UISearchBar, i.e. the content offset should be the of tableHeaderView.
Setting contentOffset, etc. didn't help when the table view wouldn't fill the view's frame.
Here's a screenshot of the current behavior:
(source: tubtub.de)
And how I'd like it to have:
(source: tubtub.de)
I'm inserting the headerView in viewDidLoad as follows:
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
headerView.backgroundColor = [UIColor redColor];
self.tableView.tableHeaderView = headerView;
}
Any help or hint is highly appreciated. Thanks!
EDIT: I made it working by utilizing UIScrollViewDelegate and subclassing UITableView. Check it out on the github repo provided.
You can use setContentOffset: by headerView height.
This contentOffset will only happen when you have enough number of data to be off by your headerView height. i.e) If tableView is not scrollable because you have only few data like one in your screenshot, the headerView is still visible. However if you have lots of number of data that can't not be displayed in the screen it will have contentOffset.
Try this with 20 rows. You will see what I mean.
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
headerView.backgroundColor = [UIColor redColor];
self.tableView.tableHeaderView = headerView;
[self.tableView setContentOffset:CGPointMake(0, 44)];
With only 3 rows, this contentOffset won't work and it might be desired behavior in your case because you don't want to hide the searchBar when you have extra space to display.
I came up with implementing my own solution.
I utilize UIScrollViewDelegate and came up with a subclass of UITableView for calculating the contentSize dynamically.
Take a look at the github repo here.
I would double check the frame for the table itself. By setting the headerView's frame to start at 0,0, you are specifying that it should have its origin in the top left of the the view that is designated for the table.

ios UICollectionView separation on top / bottom between cells

I have a collection view, is working fine, and I have adjusted the separation for the X padding,
and it works fine,
but for the Y padding between cells, doesn't seem to adjust to NO separation
This is my code for the layout
UICollectionViewFlowLayout *layoutItem=[[UICollectionViewFlowLayout alloc] init];
layoutItem.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
So how can I set the separation on top / bottom to 0px? Between cells?,
thanks!
you will see only top y padding at first time.
And For showing bottom y padding you need more data that CollectionView frame height. When you scroll up collection view you will see bottom y padding.
I used collectionView like this
https://stackoverflow.com/a/17856406/1305001
When I set
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
return UIEdgeInsetsMake(60, 10, 50, 10);
}
The output will come as First time..
When you scrolled up collectionView you will see bottom padding..
Use this for verticle line spacing between cells
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
return 5;
}
Will look like
You can also do it a much simpler way using the collection view flow layout.
Set up the flow layout (remember to add the delegate in your header):
UICollectionViewFlowLayout * stickerFlowLayout = [[UICollectionViewFlowLayout alloc] init];
stickerFlowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
**stickerFlowLayout.minimumLineSpacing = 10;**
stickerFlowLayout.minimumInteritemSpacing = 5;
stickerFlowLayout.sectionInset = UIEdgeInsetsMake(10, 25, 20, 25);
// Set up the collection view
collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:stickerFlowLayout];
collectionView.delegate = self;
collectionView.dataSource = self;
etc
As you can see we can easily set the line spacing using:
**stickerFlowLayout.minimumLineSpacing = 10;**
We can also alter the other attributes
stickerFlowLayout.minimumInteritemSpacing = 5;
With the interitem spacing affecting the spaces between items (similar but different to the line spacing)
Using the flow layout you can save on a huge amount of code and set your collection view up programatically all in one place (just setting the inset and line spacing has immediately saved me two extra unneeded functions)

Resources