Centering subview on ViewController - ios

Simply as the title says, I'm trying to center one Activity Indicator on the center of my View by doing that:
activityIndicator.center = self.view.center
activityIndicator.hidesWhenStopped = true
self.view.addSubview(activityIndicator)
but I end up with this result:
the problem persists within all view controllers in this app, except for the last one, that really centers it as you can see:

Xcode 10 / Swift 4
It can be the hight of the tab bar is disturbing. anyways,
If your code (.center) doesn't work, try this:
activityIndicator.frame = CGRect.init(x: view.frame.size.width / 2, y: view.frame.size.height / 2, width: 0, height: 0)
If it still doesn't work, change y: view.frame.size.height / 2 - "THE HIGHT OF TAB BAR".

Related

Add labels to navigation bar

I am adding a calendar to my app and thought it would be cool to mimic the format of standard iOS Calendar app as per weekday labels:
In the Calendar app, these labels (S,M,T,W,T,F,S) seem to be integrated into the navigation bar, so I was wondering if there is a way to implement this or if this is something Apple left to themselves (as there seems to be no standard way to add anything but bar button items). Mind you, these labels should be dynamic - e.g. rearrange in case of day 2 as firstWeekDay for certain Locale.
Apple proposes not to resize navigationBar itself, but remove shadow from bar and add custom view under your navigationBar.
Please refer the apple recommended approach for extended navigation bars here - https://developer.apple.com/library/content/samplecode/NavBar/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007418-Intro-DontLinkElementID_2
And your particular scenario - https://developer.apple.com/library/content/samplecode/NavBar/Listings/NavBar_ExtendedNavBar_ExtendedNavBarViewController_swift.html#//apple_ref/doc/uid/DTS40007418-NavBar_ExtendedNavBar_ExtendedNavBarViewController_swift-DontLinkElementID_13
You just need to set a view to your title view of navigationItem for example:
sampleLabel.textAlignment = .center
sampleLabel.textColor = UIColor.white
sampleLabel.font = UIFont.systemFont(ofSize: 12, weight: .medium)
sampleLabel.frame = CGRect(x: 0, y: 0, width: 40, height: 30)
sampleLabel.text = "T"
let titleView = UIView
titleView.frame = CGRect(x: 0, y: 0, width: 200, height: 50)
titleView.addSubview(sampleLabel)
navigationItem.titleView = titleView
You can add labels to your navigationBar like sampleLabel wherever you want.

UIScrollView starts out halfway down content [duplicate]

This question already has answers here:
Why is UIScrollView leaving space on top and does not scroll to the bottom
(13 answers)
Closed 6 years ago.
I am trying to implement a UIScrollView in a similar fashion to the featured banner at the top of the App Store. I am adding 3 views and then paging through them using the code below. When the controller loads however, it is started with the content down a bit. If I tap on the view the content goes back into where it should be. How can I fix this? I've trying setting the content offset to 0, I've tried manually scrolling to the origin rect, and I've tried putting my views in a content view, but nothing has worked.
featuredScrollView.alwaysBounceVertical = false
featuredScrollView.contentSize = CGSize(width: 3 * featuredScrollView.frame.size.width, height: featuredScrollView.frame.size.height)
let contentView = UIView(frame: CGRect(x: 0, y: 0, width: 3 * featuredScrollView.frame.size.width, height: featuredScrollView.frame.size.height))
featuredScrollView.addSubview(contentView)
for i in 0..<3
{
let testView = UIView(frame: CGRect(x: CGFloat(i) * featuredScrollView.bounds.size.width, y: 0, width: featuredScrollView.bounds.size.width, height: featuredScrollView.bounds.size.height))
testView.backgroundColor = .blue
testView.layer.borderColor = UIColor.white.cgColor
testView.layer.borderWidth = 1
contentView.addSubview(testView)
}
Did you try set automaticallyAdjustsScrollViewInsets to NO?

UITextField custom underline in Swift

I have a question about making an underline on UITextField.
I am trying to make an underline with bar on each end as shown below.
I tried the following and got this one. There is no bar on the right end.
extension UITextField {
func underline() {
let borderWidth = CGFloat(1.0)
let endBorderHeight = CGFloat(10.0)
let bottom = CALayer()
bottom.frame = CGRect(
x: 1,
y: self.frame.height - borderWidth,
width: self.frame.width - 2,
height: borderWidth)
bottom.borderWidth = borderWidth
bottom.borderColor = UIColor.lightGrayColor().CGColor
let leftEndBorder = CALayer()
leftEndBorder.frame = CGRect(
x: 0,
y: self.frame.height - endBorderHeight,
width: borderWidth,
height: endBorderHeight)
leftEndBorder.borderWidth = borderWidth
leftEndBorder.borderColor = UIColor.lightGrayColor().CGColor
print(bottom.frame.width)
let rightEndBorder = CALayer()
rightEndBorder.frame = CGRect(
x: self.frame.width - 1,
y: self.frame.height - endBorderHeight,
width: borderWidth,
height: endBorderHeight)
rightEndBorder.borderWidth = borderWidth
rightEndBorder.borderColor = UIColor.lightGrayColor().CGColor
self.layer.addSublayer(leftEndBorder)
self.layer.addSublayer(bottom)
self.layer.addSublayer(rightEndBorder)
self.layer.masksToBounds = true
}
}
I could make the bar on left side but having trouble making the right side because of the wrong x position of the rightEndBorder probably?
Can anyone tell me what I am doing wrong??
----- edit
I tried to set the x-position of the rightEndBorder to 200 and it gave me the following.
But if I tried to set it to 300, I don't see it anymore.
----- edit
Checked if the entire textfield was shown on the screen.
----- edit
It was that the leading and trailing constraints that changed the width of the textField I guess.
----- Solution
The problem was that I had leading and trailing constraints on the textField and those constraints changed the width after the unline was inserted. After searching google, I figured that I had to make the underline after the constraints were applied which is in the function viewDidLayoutSubviews().
Re-typing from comments section as an answer.
The problem seems to be either that the view is getting cut off (thus you will not see the right border) or the right end border is being shifted farther right after setting. Reason for suspecting this is from your picture where the right border is placed at x = 200 because it is well past half along the bottom border line but should be only be 40% of the way along the line.
Update:
The correct answer to this question was the constraints imposed caused the textfield width to change.

Sizing of Live Views in Swift Playground

I'm having trouble figuring out how to lay out views in Swift Playgrounds for iPad, though this may also be relevant to Mac users.
The following code should create a view with a red square (also a view) that is near the edges of its' super view, but not touching them.
let v = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
let sqv = UIView(frame: CGRect(x: 400, y: 400, width: 50, height: 50))
sqv.backgroundColor = .red
v.addSubview(sqv)
PlaygroundPage.current.liveView = v
The result is not what you'd expect:
I suspect I know what is going on here; live views are at a fixed size that is larger than the display area. Some characteristics of the view are ignored when it is acting as the live view. However, I can't find where this is mentioned in the documentation, which vexes me. More importantly, how do I deal with this? I would like to be able to layout simple UIs that change to fit the current size of the live view. I don't know how to address this issue without trial & error and hardcoding, which are two things I would really like to avoid.
I suspect I know what is going on here; live views are at a fixed size that is larger than the display area.
Actually it's more like the other way around. An iPad screen is 1024 points wide (in landscape orientation). The right-hand pane (where it shows your live view) is 512 points wide. The playground forces your root view (v) to fill that pane, inset by 40 points on the left, right, and top (and more on the bottom). So your root view's width is forced to 432 ( = 512 - 2 * 40), less than the 500 you specified.
Views created in code (like yours) have translatesAutoresizingMaskIntoConstraints = true, and a resizing mask of 0, which means don't adjust the view's frame at all when its parent is resized. So the playground resizes your root view to width 432, but your root view doesn't move or resize its subview (sqv).
The easiest fix is to set the autoresizing mask of the subview to express your intent that it remain near the right and bottom edges of the root view. That means it should have flexible top and left margins:
let v = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
let sqv = UIView(frame: CGRect(x: 400, y: 400, width: 50, height: 50))
sqv.autoresizingMask = [.flexibleLeftMargin, .flexibleTopMargin]
sqv.backgroundColor = .red
v.addSubview(sqv)
PlaygroundPage.current.liveView = v
Result:
let sqv = UIView(frame: CGRect(x: UIScreen.mainScreen().bounds.width-50-1, y:400, width: 50, height: 50))
The above code places your subview 1 point away from the right of the main view. Try changing the value 1 after 50 in x to desired value.

UIView not displaying in given frame

I am trying to create two drop down menu's side by side in swift. So far it consists of a UIView (created using a NIB) then two UIView's created in code that is used as a wrapper for the two UITableView's which will be displayed when the drop down menu is pressed. I have gotten the left hand menu (Leaderboard Menu) working perfectly but when I'm trying to create the 2nd menu the exact same way it is not displaying when the 2nd menu is pressed. For some reason if the x value of the frame is any more than 194 it is not displayed, my guess is that the 2nd menu is being added as a subview of the first but since the first's bounds is only 194 wide it is outside of the bounds to be displayed for that view. I will give a bit of code to show what I am trying to do. Thank you for any responses!
let leaderboardMenuFrame = CGRect(x: 0.0, y: 0.0, width: 194.0, height: leaderboardTableHeight)
let rankingMenuFrame = CGRect(x: 195.0, y: 0.0, width: 92.0, height: rankingTableHeight)
// Set up leaderboard DropdownMenu
self.leaderboardMenuWrapper = UIView(frame: leaderboardMenuFrame)
self.leaderboardMenuWrapper.clipsToBounds = true
self.leaderboardMenuWrapper.autoresizingMask = UIViewAutoresizing.FlexibleWidth.union(UIViewAutoresizing.FlexibleHeight)
// Set up ranking DropdownMenu
self.rankingMenuWrapper = UIView(frame: rankingMenuFrame)
self.rankingMenuWrapper.clipsToBounds = true
self.rankingMenuWrapper.autoresizingMask = UIViewAutoresizing.FlexibleWidth.union(UIViewAutoresizing.FlexibleHeight)
//Init Leaderboard menu table view
self.leaderboardMenuTableView = DropDownTableView(frame: CGRectMake(leaderboardMenuFrame.origin.x, leaderboardMenuFrame.origin.y + 0.5, leaderboardMenuFrame.width, leaderboardMenuFrame.height+300))
//Init Ranking menu table view
self.rankingMenuTableView = DropDownTableView(frame: CGRectMake(rankingMenuFrame.origin.x, rankingMenuFrame.origin.y + 0.5, rankingMenuFrame.width, rankingMenuFrame.height+300))
self.leaderboardMenuWrapper.addSubview(self.leaderboardMenuTableView)
self.rankingMenuWrapper.addSubview(self.rankingMenuTableView)
view = loadViewFromNib()
view.frame = bounds
view.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight]
// Add Menu View to container view
view.addSubview(self.rankingMenuWrapper)
view.addSubview(self.leaderboardMenuWrapper)
addSubview(view)
I guess the issue is this line of code:
//Init Ranking menu table view
self.rankingMenuTableView = DropDownTableView(frame: CGRectMake(rankingMenuFrame.origin.x, rankingMenuFrame.origin.y + 0.5, rankingMenuFrame.width, rankingMenuFrame.height+300))
The origin of the rankingMenuTableView should be x = 0. But as you are using the rankingMenuFrame to init the frame of the rankingMenuTableView its origin would be x = 195. This will push your rankingMenuTableView out of bounds.
So the correct way to achieve what you want should be:
//Init Ranking menu table view
self.rankingMenuTableView = DropDownTableView(frame: CGRectMake(0, rankingMenuFrame.origin.y + 0.5, rankingMenuFrame.width, rankingMenuFrame.height+300))
Hope this helps.

Resources