Frame on ViewController - ios

I have this class:
extension UIViewController {
func waiting() -> UIView{
let strLabel = UILabel(frame: CGRect(x: 50, y: 0, width: 200, height: 50))
strLabel.text = "Aguarde..."
strLabel.textColor = UIColor.whiteColor()
let messageFrame = UIView(frame: CGRect(x: view.frame.midX - 90, y: view.frame.midY - 25 , width: 180, height: 50))
messageFrame.layer.cornerRadius = 15
messageFrame.backgroundColor = UIColor(white: 0, alpha: 0.40)
let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.White)
activityIndicator.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
activityIndicator.startAnimating()
messageFrame.addSubview(activityIndicator)
messageFrame.addSubview(strLabel)
view.addSubview(messageFrame)
return messageFrame
}
}
When I need use this class I use:
class MyController: UIViewController{
....
func x(){
let messageFrame = waiting()
//my code
messageFrame.removeFromSuperview()
}
}
The problem is when the frame is showed if I touch anywhere on my app this frame is hidden. I need that when this frame is showed other options staying disabled, when I finish the frame, the options of app is enabled again. How can I do it?

Change the view that you are returning a bit:
Make a "container" view that has the same frame as the view controller's view. Give this view a "clear" background.
Make a "background" view, same size as the "container" view and add it to the container. Give this view a black background and an alpha of, say, 0.4.
Now put the view that you are currently building in your "waiting" method, and add it to the "container" view (NOT to the background view, this should be a sibling of the background view, otherwise your alert will also be transparent).
Make sure all user interaction is disabled on your views (might only need it disabled on the "container" view).
This gives you a container view that covers the entire screen, and it has 2 children: a transparent background of the same size, and your current "waiting" alert thing.
Now if you add the "container" view to your view controller's view, the user can only touch on the container view which does nothing.
(Keep in mind that this doesn't handle screen rotation...you will have to do that yourself if needed.)

Related

UIView with round corners has black background

I am trying to create a UIView with round corners the round corners are rendering perfectly but there is an odd black background behind the view. How do I get rid of the black background?
CODE
import UIKit
import PlaygroundSupport
// The background rectange for main view
let backgroundRectangle = CGRect(x: 0, y: 0, width: 500, height: 500)
// Main view
let mainView = UIView(frame: backgroundRectangle)
// Color of the main view
mainView.backgroundColor = .darkGray
// Corner radius
mainView.layer.cornerRadius = 50
mainView.layer.masksToBounds = false
// Present the view to Playground's live view
PlaygroundPage.current.liveView = mainView
RENDERED UI
EDIT
import UIKit
import PlaygroundSupport
// Holder rectangle
let holderRectangle = CGRect(x: 0, y: 0, width: 500, height: 500)
// Holder view
let holderView = UIView(frame: holderRectangle)
// The background color of the holder view is clear
holderView.backgroundColor = .clear
// Main rectangle
let mainRectangle = CGRect(x: 0, y: 0, width: 500, height: 500)
// Main view
let mainView = UIView(frame: mainRectangle)
// The background color of the main view is black
mainView.backgroundColor = .white
// Create a corner radius for the main view
mainView.layer.cornerRadius = 30
mainView.layer.masksToBounds = false
// Make the main view a subview of the holder view
holderView.addSubview(mainView)
// Present the holder view in the live view
PlaygroundPage.current.liveView = holderView
This is happening because, there is no other view present behind your mainView. Please add a view behind mainView or embed your mainView into UIView assign a background color of your choice to the newly created view. Thats it your issue resolved.

Getting details about the pinch gesture in ARKit

In my project I have a pinch to resize option for the object that has been placed in scene view. But when someone pinch the screen to reduce or enlarge the actual size of the object I need to get that scale. I need to display the scale in which the object is being changed in the screen. How do I get the scale when the action is being performed?
Thank you
Within your main ViewController Class for the ARSCNView
declare the label view, and the label itself at the top.
let scaleLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 300, 70))
let labelView = UIView(frame: CGRect(x: 300, y: 300, width: 300, height: 70))
Now within LoadView or ViewDidLoad you can set the attributes for the label such backgroundColor, textColor etc... and also add the view and label to sceneView.
// add your attributes for label,view
labelView.backgroundColor = .clear
scaleLabel.textColor = .white
scaleLabel.adjustsFontSizeToFitWidth
// add you views to sceneView
labelView.addSubview(scaleLabel)
sceneView.addSubview(labelView)
Lastly, with the pinch gesture function for scaling.. which should look something like this.
#objc func pinchGesture(_ gesture: UIPinchGestureRecognizer) {
if nodeYouScale != nil {
let action = SCNAction.scale(by: gesture.scale, duration: 0.1)
nodeYouScale.runAction(action)
gesture.scale = 1
// this part updates the label with the current scale factor
scaleLabel.text = "X: \(nodeYouScale.scale.x) Y: \(nodeYouScale.scale.y) Z:\(nodeYouScale.scale.z)"
} else {
return
}

Reproducing Music App's NavigationBar Animation

In my project I want to achieve a very similar animation like in the Artist-ViewController of the stock Music App.
When the UITableView scrolls to a specific offset the navigationBar's tintColor, the color of the title and the color of the statusbar changes.
To achieve that I added an UIView (I named it containerView) as a subView of the UINavigationBar and inside that containerView I added a UIBlurEffect. Now when the tableView scrolls I am listening to scrollViewDidScroll to change the earlier named attributes which works really good.
containerView.frame = CGRect(x: 0, y: -(statusBarHeight), width: UIScreen.main.bounds.width, height: frame.height + statusBarHeight)
containerView.clipsToBounds = true
insertSubview(containerView, at: 0)
let blurEffect = UIBlurEffect(style: .extraLight)
overlayView.effect = blurEffect
overlayView.backgroundColor = unOverlayColor
let height = frame.height + statusBarHeight
overlayView.frame = CGRect(x: 0, y: containerView.frame.height, width: containerView.frame.width, height: height)
containerView.addSubview(overlayView)
My only problem is that the containerView is placed above the UINavigationBar's navigationItems and therefore hides them.
So my question is how can I add the containerView behind the navigationItems to the UINavigationBar?
I figured out that it has to be something with the way how navigationBars are handled in iOS 11 because on iOS 10 everything works fine.

Can't manipulate subview properties after it has been added to superview - iOS Swift

I'm trying to add a UIActivityIndicatorView to a button. The problem is, once the activity indicator view is added as a subview, I can no longer do anything with it. Here's my code below:
saveAiv = UIActivityIndicatorView(frame: CGRect(x: 10, y: 10, width: 20, height: 20))
saveAiv.color = .white
saveAiv.startAnimating()
saveAiv.isHidden = false
startQuizButton.addSubview(saveAiv)
self.view.addSubview(startQuizButton)
If I call startAnimating() and set isHidden before the subview is added, it works, but if I try to do anything with the activity view after it's added it has no effect. What is going on here?

Add children view controller in a controller that pushed in a navigation controller

I had a simple view controller called ViewController, it is in a navigation stack, the structure is like following:
UINavigationControlelr
UIViewController
ViewController
The ViewController had a children view controller called a, I add a to ViewController, a's frame is ViewController's bounds. I have two another UIViewController called b and c, I add b and c to a. b's frame is
CGRect(x: 0, y: 0, width: 100, height: 100)
c's frame is
CGRect(x: 0, y: 100, width: 100, height: 100)
If I set the navigation bar translucent to true, the view shows right, like below:
But when I set the navigation bar translucent to false, something weird happened.
What's going on. How to fix that problem?
The project is simple, you can also download from here to test the problem: download
The problem cause is by default UIViewController's view has FlexibleWidth &
FlexibleHeight
bController and cController's view has extra gap 64 pixel (navBar(44) + status bar(20)). Now when you resize it has those 'FlexibleWidth&FlexibleHeight` to play with.
Solution could be making autoresizingMask to .None
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.greenColor()
bController = b()
cController = c()
bController.view.autoresizingMask = .None
cController.view.autoresizingMask = .None
displayContentController(bController, toFrame: CGRect(x: 0, y: 0, width: 100, height: 100))
displayContentController(cController, toFrame: CGRect(x: 0, y: 100, width: 100, height: 100))
}
You are setting view frames in viewDidLoad, please note that view layout is not done until much later. viewWillLayoutSubviews and viewDidLayoutSubviews, respectively, are called before and after the layout occurs).
Move your frame setting code to viewDidLayoutSubviews and it will work fine.
NOTE:: You could also get away with setting the view's frame in viewWillAppear but that's the the right place to set frames. viewWillAppear is called just before view is about to appear, view layout can change after the view has appeared (e.g. in response to device rotation).

Resources