UITabBarController icons changing height on touch - ios

I have an issue with UITabBarController, the icons are changing size if I keep my finger on them and drag up or down, they are losing height by my dragging action, how can I stop that?
Here is my code:
override func viewWillAppear(_ animated: Bool) {
.................
vc_friends.tabBarItem.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -5, right: 0)
vc_topCharts.tabBarItem.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -5, right: 0)
vc_newsfeed.tabBarItem.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -5, right: 0)
vc_myProfile.tabBarItem.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -5, right: 0)
vc_pools.tabBarItem.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -5, right: 0)
self.viewControllers = [vc_friends,vc_topCharts,vc_newsfeed,vc_pools,vc_myProfile]
self.selectedIndex = 2
}
This is how it looks like:
...and this if I click on it and keep my finger on it and move my finger up or down:

This is a known issue when your negative value is not the opposite of the positive value in the other direction. Change your insets to this:
UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)

Related

How to set the margin of backBarButtonItem?

How to set the margin of backBarButtonItem ?
Using these methods has no effect:
backItem.imageInsets = UIEdgeInsets(top: 0, left: 100, bottom: 0, right: 0)
backItem.width = 100
self.viewControllers.last?.navigationItem.backBarButtonItem = backItem

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

UIView wont appear

I have a function in my viewController that lays out my views using SnapKit. The funcion looks like this
#objc func setupView(){
//will add the scroll view to the subview
view.addSubview(scrollView)
scrollView.addSubview(imageContainer)
scrollView.addSubview(eventInfoVIew)
// scrollView.addSubview(currentEventImage)
scrollView.contentInsetAdjustmentBehavior = .never
scrollView.backgroundColor = .green
eventInfoVIew.backgroundColor = .red
imageContainer.backgroundColor = .blue
scrollView.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
imageContainer.anchor(top: scrollView.topAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: view.frame.width, height: view.frame.height - 200)
eventInfoVIew.anchor(top: imageContainer.bottomAnchor, left: view.leftAnchor, bottom: scrollView.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.scrollIndicatorInsets = view.safeAreaInsets
scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: view.safeAreaInsets.bottom, right: 0)
}
However when I run the app one of the views isn't there and it makes no sense because to the best of my knowledge I laid out the constraints properly. The eventInfoView is the one giving me problems.
Sorry forgot to add image of current screen
Have you try debugging with the view inspector? What happens with your views? A screenshot of the view hierarchy would help a lot.
Without this, my hunch is that you are not using enough constraints and therefore your layout is ambiguous. Don't forget that UIScrollView requires 6 constraints to layout properly instead of 4.
Edit: If you want to check if the scrollView is the issue, try adding this code inside
scrollView.snp.makeConstraints { (make) in
make.edges.equalTo(view)
make.width.height.equalTo(view)
}

Constraint Issue

So I have a cell that is setup to have a collectionView inside of it. The height for that cell is given in this function.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if indexPath.section == 0 {
return CGSize(width: view.frame.width, height: 300)
}
return CGSize(width: view.frame.width, height: 280)
}
Inside the class for this cell I create a collectionView and again create a collection of cells inside of it.
#objc func setupViews(){
backgroundColor = .red
addSubview(categoryCollectionView)
addSubview(sectionNameLabel)
sectionNameLabel.anchor(top: topAnchor, left: leftAnchor, bottom: nil, right: nil, paddingTop: 0, paddingLeft: 14, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
categoryCollectionView.anchor(top: sectionNameLabel.bottomAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
categoryCollectionView.delegate = self
categoryCollectionView.dataSource = self
categoryCollectionView.showsHorizontalScrollIndicator = false
categoryCollectionView.register(CategoryEventCell.self, forCellWithReuseIdentifier: cellID)
}
Each cell has a background image and a title that is below the image. However the text is always somewhat cut off. My current constraints are here
#objc func setupViews(){
backgroundColor = .clear
setCellShadow()
addSubview(backgroundImageView)
addSubview(eventNameLabel)
backgroundImageView.anchor(top: topAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 9, paddingRight: 0, width: 0, height: 0)
eventNameLabel.anchor(top: backgroundImageView.bottomAnchor, left: leftAnchor, bottom: nil, right: nil, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
}
How would I change my constraints or text/element size to make sure everything fits?
My current view looks like so
You are pinning the image to the bottom of its cell, and the label has no say in how to fit in. Instead you should pin the image's to the label's top, and the label's bottom to the cell's bottom. Like this in the visual format language: [image]-[label]-|. You also need to edit the backgroundImageView's content compression resistance.
Here is the fixed version where the label causes the image's height to shrink upwards to fit in:
#objc func setupViews(){
backgroundColor = .clear
setCellShadow()
addSubview(backgroundImageView)
addSubview(eventNameLabel)
// ensure the image compresses, not the eventNameLabel, by lowering its priority
backgroundImageView.setContentCompressionResistancePriority(UILayoutPriority(600), for: .vertical)
backgroundImageView.anchor(top: topAnchor, left: leftAnchor, bottom: eventNameLabel.topAnchor, right: rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
eventNameLabel.anchor(top: backgroundImageView.bottomAnchor, left: leftAnchor, bottom: bottomAnchor, right: nil, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
}

Add UIView behind iPhone X status bar

I have an App, that doesn't have a UINavigationController and it has a UICollectionView with some cells as its feed.
To avoid the cells appearing behind the status bar, I added a UIView behind it.
Before iPhone X it was pretty simple to do this, as the following:
let v = UIView()
v.backgroundColor = .white
view.addSubview(v)
v.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 0, paddinfLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 20)
By doing so, a tiny white layer would appear behind it as expected.
(this anchor method is from an extension, not language-default).
How can I achieve this for iPhone X ?
So far I tried the following code:
if #available(iOS 11, *) {
v.anchor(top: view.safeAreaLayoutGuide.topAnchor, left: view.safeAreaLayoutGuide.leftAnchor, bottom: nil, right: view.safeAreaLayoutGuide.rightAnchor, paddingTop: 0, paddinfLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 20)
let window = UIWindow(frame: UIScreen.main.bounds)
print("window.safeAreaInsets.top:", window.safeAreaInsets.top)
if window.safeAreaInsets.top > CGFloat(0.0) {
print("iPhone X")
v.anchor(top: view.safeAreaLayoutGuide.topAnchor, left: view.safeAreaLayoutGuide.leftAnchor, bottom: nil, right: view.safeAreaLayoutGuide.rightAnchor, paddingTop:-44, paddinfLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: window.safeAreaInsets.top)
} else {
v.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 0, paddinfLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 20)
}
}
but it doesn't work.
What's the best approach in this case?
Thank you
You have to tell your collectionView to adjust the insets:
if #available(iOS 11, *) {
collectionView.contentInsetAdjustmentBehavior = .scrollableAxes
}
This will make sure your content will be inset enough so it's not overlapped by the iPhone X's status bar.

Resources