UITableView Section Header Stop Position - ios

Is it possible to give the section header in ui tableview an offset to stop programmatically?
So, that the section header stop 100 px from top?

I think this should work:
override func scrollViewDidScroll(_ scrollView: UIScrollView)
{
super.scrollViewDidScroll(scrollView)
let inset: CGFloat = 73
if scrollView.contentOffset.y < inset && scrollView.contentOffset.y > 0 {
scrollView.contentInset = UIEdgeInsets(top: scrollView.contentOffset.y, left: 0, bottom: 0, right: 0)
} else {
if scrollView.contentOffset.y < 0 {
scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
} else {
scrollView.contentInset = UIEdgeInsets(top: inset, left: 0, bottom: 0, right: 0)
}
}
}

You can try this one
CGFloat newViewHeight = 40;
UIView *newView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, newViewHeight)];
self.tableView.tableHeaderView = newView;
self.tableView.contentInset = UIEdgeInsetsMake(-newViewHeight, 0, 0, 0);
Section headers will now scroll just like any regular cell.

You can use property of UIScrollView: contentInset. And style for a table view UITableViewStyleGrouped (.group in Swift).
This is my example of such UI:
If you want to avoid header moving, set Bounce Vertical property to NO.

Related

UIcollectionViewCell disappear when UICollectionView.contentInset set

My problem is..
when I set contentInset like below
membershipCollectionView.contentInset = UIEdgeInsets(top: 1, left: 0, bottom: 1, right: 0)
UICollectionViewCell disappear. If I change the parameter value of top, bottom to 0 it appears. Is there anyone who explain this disappearing situation?
On contentInset = UIEdgeInsets(top: 1, left: 0, bottom: 1, right: 0)
On contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
Here is my UICollectionView and UICollectionViewCell
UICollectionView
height = 50
also I set estimatedItemSize to automaticSize
#IBOutlet weak var collectionLayout: UICollectionViewFlowLayout! {
didSet {
collectionLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
}
}
UICollectionViewCell
height = 40
this is label inside UICollectionViewCell. Height is 40

Swift PDFView jumps when frame is animated

I have an app that has a fullscreen PDFView, and I'm trying to add an animatable tab bar on the top of the screen. However, any time I animate the PDFView's frame to show the tab bar, the PDF loaded in the view jumps to another position.
I've tried to animate with UIView.animate and with UIViewPropertyAnimator, and adding the PDFView as a subview and animating the parent, but all result in the same problem.
Has anyone encountered this problem? Any ideas on how to create the animation in a way that would result in a smooth user experience? The tab bar could obviously animate itself on top of the PDFView, but I don't like the idea of it covering the PDF.
Thanks!
func CreatePDFView() {
pdfView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
view.addSubview(pdfView)
}
func AnimatePDFView() {
UIView.animate(withDuration: 1) {
self.pdfView.frame = CGRect(x: 0, y: 40, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height - 40)
}
}
I've been looking to add this functionality for months, but haven't been able to solve this. As soon as I asked this question, though, it seems that I did.
You need to animate pdfView.documentView?.frame, and compensate for the current frame. I did this with UIEdgeInsets, and it seems to work.
if tabDocumentBrowserIsVisible {
tabDocumentBrowser.Animate(toState: .hidden)
UIView.animate(withDuration: 0.3) {
let inset = UIEdgeInsets(top: -80, left: 0, bottom: 0, right: 0)
self.pdfView.documentView?.frame = self.pdfView.documentView?.frame.inset(by: inset) as! CGRect
}
tabDocumentBrowserIsVisible = false
} else {
tabDocumentBrowser.Animate(toState: .visible)
UIView.animate(withDuration: 0.3) {
let inset = UIEdgeInsets(top: 80, left: 0, bottom: 0, right: 0)
self.pdfView.documentView?.frame = self.pdfView.documentView?.frame.inset(by: inset) as! CGRect
}
tabDocumentBrowserIsVisible = true
}
The PDF still behaves a bit funny if you are scrolling it while you animate it, but it's not too bad.

The space between title and text on UIButton is not correct when adjusting titleEdgeInsets and imageEdgeInsets

I want to adjust the space between text and image on UIButton,
let space = 10
button.contentHorizontalAlignment = .left
button.titleEdgeInsets = UIEdgeInsets(top: 0, left: space, bottom: 0, right: 0)
It looks well, the space in the picture is absolutely 10.
And now, I want them center,
let space = 10
button.contentHorizontalAlignment = .center
button.titleEdgeInsets = UIEdgeInsets(top: 0, left: space, bottom: 0, right: 0)
It looks much smaller, and the space is only 5. I find it from Reveal.
Why the space is reduced by half?
I searched, and this tells me how to make title and image center as a single entity. And it adjust their space like this:
CGFloat spacing = 10; // the amount of spacing to appear between image and title
tabBtn.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, spacing);
tabBtn.titleEdgeInsets = UIEdgeInsetsMake(0, spacing, 0, 0);
Yes, it truly works well, but why? From the letter, the space should be 20, doesn't it?
Here is an example, any helps?
Thanks in advance.
You Didn't set imageEdgeInsets like this :
rightButton.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 10)
So total Code is here :
leftButton.contentHorizontalAlignment = .left
leftButton.imageView?.backgroundColor = .red
leftButton.titleLabel?.backgroundColor = .gray
leftButton.titleEdgeInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 0)
rightButton.contentHorizontalAlignment = .center
rightButton.imageView?.backgroundColor = .red
rightButton.titleLabel?.backgroundColor = .gray
rightButton.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 10)
rightButton.titleEdgeInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 0)
Reason:
Actually you need to set imageEdgeInsets both time left alignment or center alignment
But when its left alignment image there is no space to set Insets at the right side.
Seet this code :
leftButton.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 100)
Here is also no space .
So home you get some idea how insets work :
For your more Help :
Click here

ScrollView Doesn't scroll when keyboard appears If elements in a ContentView

I have UIScrollView which has a UIView (basically a content view) in it. In contentView, I have UITextFields and a UIButton. At first, elements are inside UIScrollView directly. When keyboard opens, If UITextField is below keyboard, scrollview scrolls to show the content. After, I put them inside a ContentView, It started nothing to work. What am I doing wrong?
I searched below posts but not sure why my code isn't working.
How do I scroll the UIScrollView when the keyboard appears?
P.S: I know there are lots of examples in the community but I'm not sure which will be best approach. When this one was working, It was a simple and light answer but not sure why not It isn't working.
#objc override func keyboardWillShow(notification: NSNotification){
//Need to calculate keyboard exact size due to Apple suggestions
if let frameValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
keyboardHeight = frameValue.cgRectValue.size.height
let contentInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardHeight, right: 0.0)
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
}
}
How I Give Constraints:
contentView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(contentView)
contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
contentView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
scrollView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(scrollView)
contentView.addSubview(TextField1)
contentView.addSubview(TextField2)
contentView.addSubview(button)
scrollView.anchor(header.bottomAnchor, left: self.view.leftAnchor, bottom: self.view.bottomAnchor, right: self.view.rightAnchor, topConstant: 20, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 0, heightConstant: 0)
TextField1.anchor(contentView.topAnchor, left: self.contentView.leftAnchor, bottom: nil, right: self.contentView.rightAnchor, topConstant: 5, leftConstant: 25, bottomConstant: 0, rightConstant: 25, widthConstant: 0, heightConstant: 70)
TextField1.widthAnchor.constraint(equalTo: self.view.widthAnchor, constant: -50).isActive = true
TextField2.anchor(TextField1.bottomAnchor, left: self.contentView.leftAnchor, bottom: nil, right: self.contentView.rightAnchor, topConstant: 5, leftConstant: 25, bottomConstant: 0, rightConstant: 25, widthConstant: 0, heightConstant: 70)
Button.anchor(TextField2.bottomAnchor, left: self.contentView.leftAnchor, bottom: self.contentView.bottomAnchor, right: self.contentView.rightAnchor, topConstant: 30, leftConstant: 25, bottomConstant: 20, rightConstant: 25, widthConstant: 0, heightConstant: 40)
EDIT: Another approach I tried (which Apple recommended). This aRect.Contains always returns true.
if let frameValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
keyboardHeight = frameValue.cgRectValue.size.height
var contentInsets: UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardHeight, right: 0.0)
scrollView.contentInset = contentInsets
scrollView.scrollIndicatorInsets = contentInsets
// If active text field is hidden by keyboard, scroll it so it's visible
// Your application might not need or want this behavior.
//CGRect(x: 0, y: self.header.frame.maxY, width: self.view.frame.width, height: self.view.frame.height - self.header.frame.maxY)
var aRect: CGRect = self.view.frame
aRect.size.height -= keyboardHeight
aRect.size.height -= header.frame.maxY
if !aRect.contains(activeTextField.frame.origin) {
var scrollPoint = CGPoint(x: 0.0, y: activeTextField.frame.origin.y - (keyboardHeight))
scrollView.setContentOffset(scrollPoint, animated: true)
}
}
The simple way to achieve this is by using IQKeyboardManager library.
Checkout the link: https://github.com/hackiftekhar/IQKeyboardManager
After an hour work, I find the solution. I'm sharing the answer instead of deleting the post cuz my problem was because UIScrollView doesn't content whole screen. There is an header and a label above UIScrollView . All of the answers in the community, target If UIScroll content whole screen.
#objc override func keyboardWillShow(notification: NSNotification){
//Need to calculate keyboard exact size due to Apple suggestions
if let frameValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
keyboardHeight = frameValue.cgRectValue.size.height
let scrollViewRect: CGRect = view.convert(scrollView.frame, from: scrollView.superview)
let hiddenScrollViewRect: CGRect = scrollViewRect.intersection(frameValue.cgRectValue)
// Figure out where the two frames overlap, and set the content offset of the scrollview appropriately
let contentInsets: UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: hiddenScrollViewRect.size.height, right: 0.0)
scrollView.contentInset = contentInsets
scrollView.scrollIndicatorInsets = contentInsets
var visibleRect: CGRect = activeTextField.frame
visibleRect = scrollView.convert(visibleRect, from: activeTextField.superview)
visibleRect = visibleRect.insetBy(dx: 0.0, dy: -5.0)
scrollView.scrollRectToVisible(visibleRect, animated: true)
}

Swift - Parallax Header View - ScrollView overlap cells

I am trying to custom a extension for Parallax Header. However, it's not working perfectly. The table header view always floats and overlaps cells.
Extension code:
extension UITableView {
func addImageHeaderView(headerView headerView: UIView, height: CGFloat) {
self.contentInset = UIEdgeInsetsMake(height, 0, 0, 0)
self.contentOffset = CGPoint(x: 0, y: -height)
self.tableHeaderView = headerView
self.tableHeaderView?.frame = CGRect(x: 0, y: 0, width: self.bounds.width, height: height)
}
func updateHeaderView(height kTableHeaderHeight: CGFloat) {
var headerRect = CGRect(x: 0, y: -kTableHeaderHeight , width: self.bounds.width, height: kTableHeaderHeight)
if self.contentOffset.y < -kTableHeaderHeight {
headerRect.origin.y = self.contentOffset.y
headerRect.size.height = -self.contentOffset.y
}
self.tableHeaderView?.frame = headerRect
}
}
Implementing Code :
tableView.addImageHeaderView(headerView: viewHeader, height: 100)
func scrollViewDidScroll(scrollView: UIScrollView) {
tableView.updateHeaderView(height: 200)
}
Am I wrong at something? Please show me if you know.
Can you please try to set the following in viewDidLoad
self.edgesForExtendedLayout = UIEdgeInsetsZero;
in swift
self.edgesForExtendedLayout = .None
Also what you can try to do is to check the result of the following
tableView.addImageHeaderView(headerView: viewHeader, height: 0)
func scrollViewDidScroll(scrollView: UIScrollView) {
tableView.updateHeaderView(height: 200)
}
please notice that i changed the height from 100 to 0
i did it because the height value will change the contentInset of your table view and this is exactly the distance from the top corner

Resources