Programmatically add label to Message App in Swift? - ios

I know this is new with iOS10 and all, but Im trying to build a simple ms messageappextension app, and all the tutorials Ive found add their labels, buttons, etc via storyboard.
I hate autlayout and don't use storyboard, so I need to find how to add elements programmatically. This is what Ive tried:
//main label
pointsLabel.frame = CGRect(x: 0, y: 0, width: view.bounds.width * 0.5, height: view.bounds.height * 0.1)
pointsLabel.center = CGPoint(x: view.bounds.width * 0.5, y: view.bounds.width * 0.7)
pointsLabel.textColor = UIColor.red
pointsLabel.textAlignment = .center
pointsLabel.text = "Testing 123"
pointsLabel.font = UIFont(name: "Helvetica", size: screenSize.height * (30/screenSize.height))
view.addSubview(pointsLabel)
This is how Id normally make a label, and this works when the MSMessagesAppViewController is in full view like this:
However when its like this even though the positioning of the center is based on view.bounds, when the view shrinks here, the label is still displayed out of view:
Ive found that this is called when the size changes, however even resetting the center here does nothing:
override func willTransition(to presentationStyle: MSMessagesAppPresentationStyle) {
// Called before the extension transitions to a new presentation style.
// Use this method to prepare for the change in presentation style.
print(view.bounds.height)
pointsLabel.center = CGPoint(x: view.bounds.width * 0.5, y: view.bounds.width * 0.7)
}
Other than just switching back in forth between different heights, what is the correct way to add a label programmatically?

Change your center calculation to use the height of the superview for y, rather than a portion of the width:
pointsLabel.center = CGPoint(x: view.bounds.width * 0.5, y: view.bounds.height * 0.5)
While compact, the width is actually greater than the height, so view.bounds.width * 0.7 was pushing your label off the screen.

Related

Swift: Changing the hight of subview programmatically

I'm implementing a subview but I need to change the subview high programmatically but. This is how I'm changing the high:
func changeHigh() {
UIView.animate(withDuration: 1.0, animations: {
self.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height - 50)
self.buttonConstraint.constant = 10
})
}
But the problem with this implementation is animating also the position of the view. All I want is to change the high with out changing the position.
Any of you knows why is changing the position of the subview?
I'll really appreciate you help.
First, to change the height, you can just modify the size.height property of the frame.
self.frame.size.height -= 50 /// this will make it 50 pts less
Also, you should change constraints outside the animation block, not inside. Then, call layoutIfNeeded() to animate it.
Here's how your code should look:
func changeHigh() {
self.buttonConstraint.constant = 10
UIView.animate(withDuration: 1.0, animations: {
self.frame.size.height -= 50
self.layoutIfNeeded()
})
}

How to adjust Subview according to different Screen Sizes (Height and Width)?

I am trying to add a view onto the screen using the following code:-
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let size = CGSize(width: 564.0, height: 783.0)
let host = UIView(frame: CGRect(x: 0.0, y: 0.0, width: size.self.width, height: size.self.height))
self.view.addSubview(host)
let particlesLayer = CAEmitterLayer()
particlesLayer.frame = CGRect(x: 0.0, y: 0.0, width: size.self.width, height: size.self.height)
host.layer.addSublayer(particlesLayer)
host.layer.masksToBounds = true
}
But, the view is not able to cover the entire screen on an iPad, but, is able to cover only the size of an iPhone screen. Could anyone please let me know what can I do to resolve this issue? Thanks a lot for the help!🙏
You can use below to get device's screen size.
let width = UIScreen.main.bounds.width
let height = UIScreen.main.bounds.height
However, you should consider using autolayout. It is more clean and useful compare to your approach.

Place view in the bottom right, hiding part, programmatically swift 5

I want to move the view as shown in the image programmatically, to obtain an effect similar to 1/4 of roulette.
But I only get it to show below as indicated in the code for one screen.
let X_Position:CGFloat? = 150.0 //use your X position here
let Y_Position:CGFloat? = 300.0 //use your Y position here
circle.frame = CGRect(x: X_Position ?? 0,y: Y_Position ?? 0,width:
circle.frame.width,height: circle.frame.height)
How can I get this position for all screens?
Swift 4
Without Animation:
let screen = UIScreen.main.bounds
let circleViewRect = circlemenu.frame
circlemenu.frame = CGRect.init(x: screen.width - circleViewRect.width/2, y: screen.height - circleViewRect.height/2, width: circleViewRect.width, height: circleViewRect.height)
With Animation:
let screen = UIScreen.main.bounds
let circleViewRect = circlemenu.frame
UIView.animate(withDuration: 0.3) {
circlemenu.frame = CGRect.init(x: screen.width - circleViewRect.width/2, y: screen.height - circleViewRect.height/2, width: circleViewRect.width, height: circleViewRect.height)
}
I believe you are using an old version of swift, so feel free to change the functions accordingly

How to set a custom background view properly with UiActivityIndicator

My app is using WKWebView to load my website. I need a UiActivityIndicator with a custom dark gray background view due to the UIActivityIndicator might be difficult to spot when it mixed up with my website's content. Previously, I followed https://coderwall.com/p/su1t1a/ios-customized-activity-indicator-with-swift to programmatically create an indicator. However, the tutorial is using default white and mine is large white with custom orange color. All I need just a backgroundView with an indicator inside of the backgroundView. Somehow it works until I noticed that the indicator is not that center and it ran off a little bit to the top left. Please see this image,
It is very obvious on my iPhone 5 and so on. So, I used another approach which is using auto layout. The background view is still not working as well. Here is my auto layout setup
This is my programmatically part.
loadingView.frame = CGRect(x: 0, y: 0, width: 60, height: 60)
loadingView.center = self.view.center
loadingView.backgroundColor = UIColor(red:211/255,green:211/255,blue:211/255, alpha: 1)
loadingView.clipsToBounds = true
loadingView.layer.cornerRadius = 10
loadingIndicator.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
loadingIndicator.isOpaque = false
loadingIndicator.center = CGPoint(x: loadingView.frame.size.width / 2.0, y: loadingView.frame.size.height / 2.0)
loadingIndicator.backgroundColor = UIColor.gray
loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.whiteLarge
loadingIndicator.color = UIColor(red:232/255,green:126/255,blue:4/255,alpha:1.0)
loadingIndicator.hidesWhenStopped = true
loadingView.addSubview(loadingIndicator)
self.view.addSubview(loadingView)
I would prefer using auto layout.
There is no issue in either your auto layout setup nor the code you are trying.
The off-center issue actually seems to be an iOS bug when setting a custom color on a UIActivityIndicatorView.
You can see this for yourself.
Drag a basic UIActivityIndicatorView
Set a background color
Set it's style to "Large White"
Now set a color
This doesn't happen when the style is White or Gray
Tested it in Xcode 9.3 Storyboard as well as Simulator with Debug > Color Blended layers - ON
Try to change this code
let loadingView = UIView()
let loadingIndicator = UIActivityIndicatorView()
loadingView.frame = CGRect(x: 0, y: 0, width: 60, height: 60)
loadingView.center = self.view.center
loadingView.backgroundColor = UIColor(red:211/255,green:211/255,blue:211/255, alpha: 1)
loadingView.clipsToBounds = true
loadingView.layer.cornerRadius = 10
loadingIndicator.frame = CGRect(x: 0, y: 0, width: 37, height: 37)
loadingIndicator.isOpaque = false
loadingIndicator.center = CGPoint(x: loadingView.bounds.size.width / 2, y: loadingView.bounds.size.height / 2)
loadingIndicator.backgroundColor = UIColor.gray
loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.whiteLarge
loadingIndicator.color = UIColor(red:232/255,green:126/255,blue:4/255,alpha:1.0)
loadingIndicator.hidesWhenStopped = true
loadingView.addSubview(loadingIndicator)
loadingIndicator.tag = 500
for subView in loadingView.subviews{
if subView.tag == 500{
print(subView.frame)
print("Bounds", subView.bounds)
}
}
loadingIndicator.startAnimating()
self.view.addSubview(loadingView)
As per style of indicator view is whiteLarge, by default its 37 so change and check.
For auto layout :
Drag UIView with 60*60 width and height.(Give width,height, horizontal center, vertical center to your super view.)
Drag Indicator view into Your UIView.(Give horizontal center, vertical center to your view.)
select Indicator view set style to white large and check its frame.(37 by default and other style 20).
set constraints like below image.

SWIFT slide one Object "in and out"

Is there a way to animate an object in swift (UIView, UIButton, etc.) so that it slides out on the left side of the screen and slides in at the same time on the right side of the screen, that the parts of f.e. an UIView that already slided out on the left side are already sliding in again from the right side.
I hope you can understand my question, its a bit tricky to explain this problem.
I'm using Xcode + Swift 3.0.
Thank you.
that the parts of f.e. an UIView that already slided out on the left side are already sliding in again from the right side
This almost slipped by me. The only way you have one "view" appear in two places on a screen is by really having two views, one on the left and one on the right.
Then, you could set the widthAnchors (properly), hide the subviews (properly), and animate. If the animation is fast enough (my one-sided slide out is set for 0.3 seconds) the user would think it's all one view.
You can use UIView.animate(). Trigger a second animation after the first has completed.
Possible implementation to get the idea:
var container = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 200.0, height: 200.0))
let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 50.0, height: 50.0))
view.center = CGPoint(x: 100, y: 100)
view.backgroundColor = UIColor.green
container.addSubview(view)
let screenWidth = CGFloat(356.0)
// animate to left
UIView.animate(withDuration: 2.0, delay: 0.0, options: [], animations: {
view.center = CGPoint(x: -view.frame.size.width, y: view.frame.origin.y)
}, completion: { (finished: Bool) in
//set view to right of screen
view.center = CGPoint(x: view.frame.size.width + screenWidth, y: view.frame.origin.y)
// animate back to center
UIView.animate(withDuration: 2.0, delay: 0.0, options: [], animations: {
view.center = CGPoint(x: 100, y: 100)
})
})

Resources