How to set constraints from page control indicator to the view - ios

Can anybody help me please?:)
How can I set constraints in a storyboard for Page Control Indicator so when I am listing my collectionView pages the indicator isn't moving.
I've tried setting constraints for page control indicator, but there is just option to set it with cell frame. So when I list a collection view indicator appears again and again on each new page.
Screenshot:

You have to set the currentpage in the pageControl. The best is at the function scrollViewWillEndDragging:
override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
let pageNumber = Int(targetContentOffset.pointee.x / view.frame.width)
pageControl.currentPage = pageNumber
}
then it will work :)

Related

Stop scrolling UITableView perfectly on cell

I have a list of cells of varying height, and I want the scroll to top perfectly at the top of a cell.
For this I can use
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
And I can set the targetContentOffset to the top of a cells frame.
However if cells yet to be laid out have a height different from their estimated height, then this destination cells origin will change, and I don't get a chance to account for this.
Is there anyway to land perfectly on a cell after a scroll when the origin can change?

Stop CollectionView from scrolling during interaction

I'm trying to stop a UICollectionView from scrolling if the velocity is too low.
Using the delegate method:
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
I've tried many different approaches, but nothing seems to stop the scrollview. I've tried combinations of:
scrollView.layer.removeAllAnimations()
scrollView.isScrollEnabled = false
scrollView.layoutIfNeeded()
You can just set the current contentOffset as a target offset.
targetContentOffset.pointee = scrollView.contentOffset

UIScrollView change contentInset while scrolling

I’m trying to implement a custom top bar that behaves similarly to the iOS 11+ large title navigation bar, where the large title section of the bar collapses when scrolling down the content:
The difference is that my bar needs a custom height and also a bottom section that doesn’t collapse when scrolled. I managed to get that part working:
The bar is implemented using a UIStackView & with some non-required layout constraints, but I believe its internal implementation is not relevant. The most important thing is that the height of the bar is tied to scrollview's top contentInset. These are driven by scrollview's contentOffset in UIScrollViewDelegate.scrollViewDidScroll method:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let topInset = (-scrollView.contentOffset.y).limitedBy(topBarHeightRange)
// changes both contentInset and scrollIndicatorInsets
adjustTopContentInset(topInset)
// changes top bar height
heightConstraint?.constant = topInset
adjustSmallTitleAlpha()
}
topBarHeightRange stores the minimum and maximum bar height
One thing that I'm having a problem with is that when the user stops scrolling the scrollview, it's possible that the bar will end up in a semi-collapsed state. Again, let's look at the desired behavior:
Content offset is snapped to either the compact or expanded height, whichever is "closer". I'm trying to achieve the same in UIScrollViewDelegate.scrollViewWillEndDragging method:
func scrollViewWillEndDragging(_ scrollView: UIScrollView,
withVelocity velocity: CGPoint,
targetContentOffset: UnsafeMutablePointer<CGPoint>) {
let targetY = targetContentOffset.pointee.y
// snaps to a "closer" value
let snappedTargetY = targetY.snappedTo([topBarHeightRange.lowerBound, topBarHeightRange.upperBound].map(-))
targetContentOffset.pointee.y = snappedTargetY
print("Snapped: \(targetY) -> \(snappedTargetY)")
}
The effect is far from perfect:
When I look at the printout it shows that the targetContentOffset is modified correctly. However, visually in the app the content offset is snapped only to the compact height but not to the expanded height (you can observe that the large "Title" label ends up being cut in half instead of back to the "expanded" position.
I suspect this issue has something to do with changing the contentInset.top while the user is scrolling, but I can't figure out how to fix this behavior.
It's a bit hard to explain the problem, so I hope the GIFs help. Here's the repo: https://github.com/AleksanderMaj/ScrollView
Any ideas how to make the scrollview/bar combo snap to compact/expanded height properly?
I took a look at your project and liked your implementation.
I came up with a solution in your scrollViewWillEndDragging method by adding the following code at the end of method:
if abs(targetY) < abs(snappedTargetY) {
scrollView.setContentOffset(CGPoint(x: 0, y: snappedTargetY), animated: true)
}
Basically, if the scroll down amount is not worth hiding the large title (it happens if targetY is less than snappedTargetY) then just scroll to value of snappedTargetY to show the large title back.
Seems to be working for now, but let me know if you encounter any bugs or find a way to improve.
Whole scrollViewWillEndDragging method:
func scrollViewWillEndDragging(_ scrollView: UIScrollView,
withVelocity velocity: CGPoint,
targetContentOffset: UnsafeMutablePointer<CGPoint>) {
let targetY = targetContentOffset.pointee.y
// snaps to a "closer" value
let snappedTargetY = targetY.snappedTo([topBarHeightRange.lowerBound, topBarHeightRange.upperBound].map(-))
targetContentOffset.pointee.y = snappedTargetY
if abs(targetY) < abs(snappedTargetY) {
scrollView.setContentOffset(CGPoint(x: 0, y: snappedTargetY), animated: true)
}
print("Snapped: \(targetY) -> \(snappedTargetY)")
}

Swift CollectionView set where to scroll

So I have a collection view horizontal and I want when the user scroll to set the scroll where I want.
#IBOutlet var joke_cards: UICollectionView!
extension ViewController: UIScrollViewDelegate{
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
joke_cards.contentOffset.x = scrollView.contentOffset.x + 1000
joke_cards.reloadData()
}
}
But this doesn't work, it scrolls normally, I want to specify how much to scroll, any suggestions?
So I think I need to be a bit more clear, what I want is to flip through some cards horizontally thats why I need when the user stars to swipe to show the next cell in the middle
If you want to manually scroll the user to a certain area you need first to define the area you need to scroll into view. This will depend a little bit on where exactly you are trying to scroll, but if the goal is just to scroll 1000 points to the right you can define the rect and scrolling like so:
let destinationRect = CGRect(x: scrollView.contentOffset.x + 1000, y: scrollView.contentOffset.y, width: 1, height: 1)
scrollView.scrollRectToVisible(destinationRect, animated: true)
Please note that scrolling will stop as soon as any part of the rect is visible, so if you want contentOffset.x + 1000 to be in the center you will need to do some more math to create the destinationRect.
The other option, since you are using a UICollectionView is to figure out which cell is at the point you want to scroll to, and scroll that cell to a certain position. In this example I safely unwrap the optional indexPath at the point you specified, and scroll that cell to be centered horizontally in the collectionView:
if let indexPath = self.joke_cards.indexPathForItem(at: CGPoint(x: scrollView.contentOffset.x, y: scrollView.frame.midY)) {
self.joke_cards.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
}

Slow animation of table view deceleration

Trying to set targetContentOffset in scrollview delegate method to snap tableView to desired position(top,middle,bottom),but after snap action the tableView decelerate to the position but its not finishing animation very fast it gets slow down after few seconds.i tried to change the speed by putting some lower number (0.97,0.96…..) but still its is same,I have also tried putting the same content in UIView animation block but there is no change in speed? How Can I speed up deceleration Rate more than UIScrollViewDecelerationRateFast?
tableView.decelerationRate = UIScrollViewDecelerationRateFast
var scrollRect:CGRect = scrollView.frame;
func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
scrollRect.origin.y = self.getNextPosition(position, previousPosition: self.previousPosition, fastScroll: isFastScroll! , andScrollDirection: self.scrollDirection!,isFrameChanged:frameChanged)
targetContentOffset.memory.y = scrollRect.origin.y
}

Resources