At the very bottom is my code where MainController initiates a subview called setController. The new subview is created when I click the button
However, within setController's code I get back a nil when I try to the superview:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("\(self.view.superview)" ?? "count->no parent")
}
I am assigning the second view as a subview, but obviously I am missing something. Have I misunderstood how UIView hierarchy works?
class MainController: UIViewController {
private lazy var setController = SetController()
var invButton : MyButton!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .black
invButton = makeButton(vControl: self, btype: ButtType.inv, action: #selector(self.buttonAction(sender:)))
invButton.frame.origin.x = self.view.frame.width * 0.1
invButton.frame.origin.y = self.view.frame.height * 0.1
invButton.setTitle("Settings", for: .normal)
}
override var prefersStatusBarHidden: Bool {
return false
}
@objc func buttonAction(sender: UIButton!) {
guard let theButton = sender as? MyButton else { return}
UIView.transition(with: self.view, duration: 0.5, options: .transitionCurlDown, animations: { [self] in
self.addChild(setController)
self.view.addSubview(setController.view)
setController.didMove(toParent: self)
}, completion: nil)
}
}
Post
Replies
Boosts
Views
Activity
Below is my code. I have the ViewController, which takes up entire screen (set background color, makes sure status bar is visible, etc.
It then calls up the MainController, which is set to be only in the safeAreaLayout frame. It has a button that brings up a third view controller when clicked.
Everything works, the ViewController covers the entire screen, the MainController rests within the safeAreaLayouts of the iPhone X, and the third view controller comes up the same size and position as the MainController.
It's that last part I want to make sure of, that that is the way it is supposed to come up. Can I count on that? Or must I set its frame myself to be sure?
ViewController
class ViewController: UIViewController {
var mainController = MainController()
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.addChild(mainController)
self.view.addSubview(mainController.view)
setConstraints(vc: mainController, pc: view)
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = bgColor
}
override var prefersStatusBarHidden: Bool {
return false
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .darkContent
}
}
func setConstraints (vc: UIViewController, pc: UIView) {
vc.view.translatesAutoresizingMaskIntoConstraints = false
var constraints = [NSLayoutConstraint]()
constraints.append(vc.view.leadingAnchor.constraint(equalTo: pc.safeAreaLayoutGuide.leadingAnchor))
constraints.append(vc.view.trailingAnchor.constraint(equalTo: pc.safeAreaLayoutGuide.trailingAnchor))
constraints.append(vc.view.bottomAnchor.constraint(equalTo: pc.safeAreaLayoutGuide.bottomAnchor))
constraints.append(vc.view.topAnchor.constraint(equalTo: pc.safeAreaLayoutGuide.topAnchor))
NSLayoutConstraint.activate(constraints)
}
MainController
class MainController: UIViewController {
private lazy var countController = CountController()
var invButton : MyButton!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .black
...button code ....
}
override var prefersStatusBarHidden: Bool {
return false
}
@objc func buttonAction(sender: UIButton!) {
guard let theButton = sender as? MyButton else { return}
self.addChild(countController)
self.view.addSubview(countController.view)
}
}
ThirdViewController
class CountController : UIViewController {
var backButton : MyButton!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .gray
}
}
When my app starts up I have my ViewController, which automatically creates my MainScreen (also a view controller). Right after
self.addChild(mainController)
I call a function which sets my constraints
func setConstraints (vc: UIViewController) {
vc.view.translatesAutoresizingMaskIntoConstraints = false
var constraints = [NSLayoutConstraint]()
constraints.append(vc.view.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor))
constraints.append(vc.view.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor))
constraints.append(vc.view.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor))
constraints.append(vc.view.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor))
NSLayoutConstraint.activate(constraints)
}
All is fine up to this point, the MainScreen is bound by the top and bottom safe areas.
At some point from MainScreen I create another UIViewController.
countController.modalPresentationStyle = .fullScreen
self.present(countController, animated: true, completion: {})
Yet, no matter how hard I try to apply the constraints to the new controller, I crash with the following msg:
Unable to activate constraint with anchors <NSLayoutXAxisAnchor....because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That's illegal."
Am too new to figure out where my error is.
I have my mainController (parent) and my menuController (child).
I call the menuController with
addChild(child)
view.addSubview(child.view)
child.didMove(toParent: self)
The child dismisses itself with:
self.dismiss(animated: true, completion: nil)
The question I have, is how do I clean up the child within the parent? Surely I have to do something?
So am watching a Speech To Text demo on YouTube, here:
https://www.youtube.com/watch?v=SZJ8zjMGUcY
There are no files, so am typing from the screen, and immediately run into an error that confuses me.
at
class ViewController : UIViewController, SFSpeechRecognizer {
here's a screenshot:
Swift gives me an error indicating that Multiple Inheritance is not allowed.
The programmer doesn't have files to download, and I like to start from scratch anyway, typing and copying so I am forced to read each line.
Is there something I have to change in the project itself that allows Multiple Inheritances?
This video is from last year, and is on Swift 5.0. So I don't think there could be that much of a major change in Swift in that time.
Thanks
So sorry if I should't be asking this here, but am trying to find a current-ish tutorial on how to make an app that converts speech to text in real time.
Transcribing from text to speech as you're speaking.
I've found a few one's on YouTube, but they are quite old, or just transcribing from a recorded file, etc. etc.
If anyone is aware of a good tutorial, paid or not, I would so appreciate any link.
Thank you
While I do need to get another HD, I currently have
34.85 GB (12.61 GB purgeable) available.
Yet for some reason when I try to run update on Xcode, it says I don't have enough HD space. That's three times the final size of the new Xcode.
Is there some way around this?
Below is a simple code patch I use to create a custom button, am new at this. I noticed the text does not appear and am wondering what the proper method is for making the text appear?
func makeButton (vControl: ViewController, action: Selector) {
let myButtonImage = UIImage(named: "Picture1.png")
let imageScale = myButtonImage!.size.width / myButtonImage!.size.height
let wwidth = vControl.self.view.bounds.width
let button = CreateButton(frame: CGRect(x: 100, y: 100, width: (myButtonImage?.size.width)!/3, height: (myButtonImage?.size.height)!/3))
button.setImage(myButtonImage, for: .normal)
button.backgroundColor = .clear
button.setTitleColor(.black, for: .normal)
button.setTitle("Test Button", for: .normal)
button.addTarget(vControl, action: action, for: .touchUpInside)
vControl.view.addSubview(button)
button.center = vControl.view.center
}
I would like to take this sample code
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
button.backgroundColor = .greenColor()
button.setTitle("Test Button", forState: .Normal)
button.addTarget(self, action: #selector(buttonAction), forControlEvents: .TouchUpInside)
self.view.addSubview(button)
}
func buttonAction(sender: UIButton!) {
print("Button tapped")
}
...and place the code to create the button in another file. So it would look more like this:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
makeButton(vControl: self)
}
@objc func buttonAction(sender: UIButton!) {
print("Button tapped")
}
}
Of course the main flaw is that I would have to pass a pointer to the function buttonAction.
Something like we do in C
makeButton(vControl: self, bFunc: &buttonAction)
Have Googled a lot but can't seem to find the way to do this. How do I set up the makeButton page to recieve this?
func makeButton (vControl: ViewController, bFunc: ???)
What would the ??? be in reality?
thanks
I have a very simple app. All SKSpriteNodes, myBall, myBlue, and myRed.
Only myBall moves, affected by gravity, and bounces off of different objects (myRed and myBlue).
What I can't figure out is how to make myBall bounce harder or softer depending on which body it hits?
I hav been playing with the density of all the objects, but it doesn't seem to make any difference? Is there some property I am unaware of? Or are there other methods?
I've created a ball, and boxed my game scene.
The balls physics settings are:
self.physicsBody!.affectedByGravity = true
self.physicsBody!.restitution = 1.0
self.physicsBody!.linearDamping = 0
self.physicsBody!.friction = 0.3
self.physicsBody!.isDynamic = true
self.physicsBody!.mass = 0.5
self.physicsBody?.contactTestBitMask = bodyMasks.blankMask.rawValue
self.physicsBody?.collisionBitMask = bodyMasks.edgeMask.rawValue
self.physicsBody?.categoryBitMask = bodyMasks.ballMask.rawValue
When I box the game scene with:
self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
the ball bounces back up as intended.
However, if I replace edgeLoopFrom with my own custom borders:
yourLine.lineWidth = 5
yourLine.path = pathToDraw
yourLine.isUserInteractionEnabled = false
yourLine.strokeColor = .clear
yourLine.isHidden = false
yourLine.zPosition = 10
yourLine.physicsBody = SKPhysicsBody(edgeLoopFrom: pathToDraw)
yourLine.physicsBody?.affectedByGravity = false
yourLine.physicsBody?.pinned = true
yourLine.physicsBody?.categoryBitMask = bodyMasks.edgeMask.rawValue
yourLine.physicsBody?.collisionBitMask = bodyMasks.ballMask.rawValue
yourLine.physicsBody?.contactTestBitMask = bodyMasks.blankMask.rawValue
the ball just comes down with a thud, stops, and doesn't bounce.,
So am trying to figure out what physics settings I have to give to my custom made edges so that the ball bounces?
I have an SkSpriteNode (ball) in a box. Gravity is set to false, otherwise it has an SkPhysicsBody to bounce off of walls.
Is there a method to give the ”ball” an initial push in a specified direction and velocity/strength wise?
I know it's uncool to ask vague questions here, but what do they call it when you create a world and follow it with a camera in Swift? Like an RPG? Like Doom?
I want to try and learn that now. And more importantly can it be done without using the Xcode scene builder? Can it be done all via code?
Thanks, as always. Without the forum I would never have gotten much farther than "Hello World!"
In my app, I have greyBars and one border bar. The border bar keeps the greyBars from falling off the screen.
Only one greyBar is used at a time. When it is completely filed with colored gems, a new bar is created and brought up from the bottom of the screen, with the code below.
The result I want is that the new bar, the one with all white diamonds pushes up the old bar and the new bar remains on the bottom. You can see by the screenshot that somehow the new bar ended up on top, even though it was coming from the bottom.
I slowed down the duration of the greyBar's movement to see what was going wrong.
While the two greyBars do clash with each other, the new one (the one on the bottom) ends up pushing THROUGH the top bar.
My assumption was that the new greyBar would just push up the old bar(s), and remain on the bottom.
Is there some "solidity" type property that I am missing?
myGreyBar[0].physicsBody?.categoryBitMask = bodyMasks.greyBarMask.rawValue
myGreyBar[0].physicsBody?.contactTestBitMask = bodyMasks.blankMask.rawValue
myGreyBar[0].physicsBody?.collisionBitMask = bodyMasks.greyBarMask.rawValue
myGreyBar[0].isHidden = false;
myGV.gameScene?.addChild(myGreyBar[0])
let moveAction = SKAction.move(to: CGPoint(x:(myGV.safeSceneRect.width/2) - (size.width/2), y: (myGemBase?.size.height)! + (myGV.border?.size.height)! + 200), duration: 10.0)
myGreyBar[0].run(moveAction, completion:{myGreyBar[0].physicsBody?.collisionBitMask = bodyMasks.borderMask.rawValue|bodyMasks.greyBarMask.rawValue})
I have an SKSpriteNode with an SKAction being run on it:
theGem!.run(premAction, completion: {theGem!.run(repeatAction)})
Can't seem to find out the proper steps to run another action, such as:
theGem.run(endsequence, completion: {theGem.removeAllActions(); theGem.run(stopAction)})
Should I stop the previous action first?
Is there a way to turn the repeat part off so that the first SKAction ends smoothly?