I'm having an issue with some container views.
The main view has 2-container views. One of them is just a container view, straight up from the drop-off menu with nothing more than it's child VC being modified via Storyboard. (the embedded one).
The second Container View has a Scroll-view inside and a second view inside the container view with a custom size. (I saw a tutorial on youtube).
Now on my viewdidload on the HomeVC I call the following code:
func setupViews() {
containerTop.layer.cornerRadius = 15
containerTop.clipToBounds = true
containerBot.layer.cornerRadius = 15
containerBot.clipToBounds = true
}
The above code results in THIS RESULTS. As you can see all but 2 corners are rounded (the bottom 2 corners of the top view). Why is this happening and how can I fix this?
I'm not 100% sure about why you are having this odd behaviour, I also experienced something similar and fixed like following: (Your project should be supporting iOS11++ in order for this solution to work:
func setupViews() {
containerTop.layer.cornerRadius = 15
containerTop.clipToBounds = true
containerBot.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner, .layerMinXMaxYCorner, .layerMaxXMaxYCorner]
containerBot.layer.cornerRadius = 15
containerBot.clipToBounds = true
}
Thank you for the suggestion. Unfortunately it didnt work.
I was able to fix it by doing the following:
On the storyboard tree On the ViewController there is a View on the element tree. I linked that as an outlet in my code and made it's corners round. Basically I called the round corners twice:
- Home View controller had:
func setupViews() {
containerTop.layer.cornerRadius = 15
containerTop.clipToBounds = true
containerBot.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner, .layerMinXMaxYCorner, .layerMaxXMaxYCorner]
containerBot.layer.cornerRadius = 15
containerBot.clipToBounds = true
}
And then the ContainerTopViewController had inside a View (per storyboard) and the code is:
class ContainerTopViewController: UIViewController {
<LINKED THROUGH STORYBOARD> myView: UIViewController
func loadView() {
myView.layer.cornerRadius = 15
myView.layer.clipToBounds = true
}
}
Related
I have a strange problem. I have a custom UIView that is supposed to fill the screen. Here is a picture of the GUI along with the constraints:
Now the main problem is, on the iPad Pro 12.9" simulator, at first the custom view only fills a portion of the screen- like it was following the Air 2 size constraints. However, if I go away from the screen and come back to it such that the screen isn't recreated but just redisplayed, the gui looks almost perfect. On the other hand, the gui looks almost perfect on the iPad Mini device that I have, without having to go and come back. It isn't quite there because the image in the middle section gets clipped slightly at the top and bottom, but I haven't tried hard to figure out why that is happening. I have spent a fair amount of time trying to debug the problem I am asking about. If you need more information to help me solve this problem, I'm happy to provide it- just specify what you need. On the view controllers that actually hold this custom view, I use autoresizing masks to have it fill the screen, which apparently isn't working, but constraints have been tried and they didn't help either.
Any ideas on how to fix this?
UPDATE: I changed the constraints to something I liked better, as I had used "Reset to Suggested Constraints" and that created some weird constraints. Problem still exists, however.
Here is some of the code involving the view:
class SessionDisplayViewController: SessionViewDisplayViewControllerBase
{
//some code omitted for succinctness
#IBOutlet weak var mySessionView: SessionDisplayView!
override func getSessionView() -> SessionDisplayView
{
return mySessionView
}
...
}
class SessionViewDisplayViewControllerBase: UIViewController, SessionDisplayViewDelegate{
...
override func viewDidLoad() {
super.viewDidLoad()
...
if !ShareData.sharedInstance.sessionDataObjectContainer.keys.contains(curSessName) || ShareData.sharedInstance.sessionDataObjectContainer[curSessName] == nil
{
setupMySession(isLive: false, isFinalized: false)
}
else if (ShareData.sharedInstance.sessionDataObjectContainer[curSessName]?.isFinalized)!
{
setupMySession(isLive: false, isFinalized: true)
}
else
{
setupMySession(isLive: true, isFinalized: false)
var fromTempChoose = ShareData.sharedInstance.startingSessionFromTempChoose && !(ShareData.sharedInstance.globalsVar?.hasStartedSession)!
if fromTempChoose || (ShareData.sharedInstance.resumingSessionFromSessDet && !(ShareData.sharedInstance.globalsVar?.hasResumedSession)!)
{
let mySessionView = getSessionView()
mySessionView.curScene.pauseSession(isStartingNow: true)
blurEffect = UIBlurEffect(style: UIBlurEffectStyle.light)
//}
blurEffectView = UIVisualEffectView(effect: blurEffect)
//always fill the view
blurEffectView?.frame = self.view.bounds
blurEffectView?.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.view.addSubview(blurEffectView!)
}
...
}
var mySessObj = getSessionView() //these three lines of code were added to try to fix the problem. They weren't in the original code
mySessObj.frame = self.view.bounds
setNeedsDisplay()
}
...
func setupMySession(isLive: Bool, isFinalized: Bool)
{
let mySessionView = getSessionView()
//mySessionView.translatesAutoresizingMaskIntoConstraints = false
mySessionView.delegate = self
sessionNameIndex = self.getSessionNumber() - 1
let myName = ShareData.sharedInstance.currentAccount.name
var curSessName = generateCurrentAccountName(name: myName!, value: self.getSessionNumber())
//var names = generateAllPossibleSessionNames(name: myName!)
let curSession = ShareData.sharedInstance.sessionDataObjectContainer[curSessName]
mySessionView.onView(index: getSessionNumber(), sessionName: curSessName, isLive: isLive, isFinalized: isFinalized)
if isLive
{
let val = curSession?.currentValue()
mySessionView.curScene.setStartPosition(newValue: val!)
}
}
It took me awhile to figure this one out. The software was adding an auto resizing mask constraint to the view, which was causing it to look funny. In order to fix this problem, in the initialization of the custom UIView, I had to add the following lines of code:
self.view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
self.view.frame = self.bounds
I guess the software treats the class that is the custom UIView and the view inside it that holds everything as two separate views. I wish the tutorials I found online about creating a custom UIView had included that we need to set the auto resizing mask and the view's frame, but oh well. Lesson learned.
Evening, I have a calendar collection.
The cells have some rounded views shown incorrectly at the first time, but when they are reloaded they are shown correctly.
I know that the issue is that at the first time the cell doesn't know the right size of the frame.
What I've tried:
1- call the round function inside layoutSubviews(): only the right side is rounded correctly
2 - call the round function inside the cellWillLayout: nothing changes
This is the rounding function:
func makeRound() {
print("rounding")
currentDayView.layer.cornerRadius = currentDayView.frame.height/2
currentDayView.layer.masksToBounds = true
currentDayView.clipsToBounds = true
selectedDayView.layer.cornerRadius = selectedDayView.frame.height/2
selectedDayView.layer.masksToBounds = true
selectedDayView.clipsToBounds = true
}
Any suggestion?
The best place to do corner rounding is either in each view's layoutSubviews or (for example, if you haven't sub-classed them) put it in your view controllers viewDidLayoutSubviews.
Each view in your case is the layoutSubviews of currentDayView and selectedDayView.
You need to override layoutSubviews method, then call your method inside it:
override func layoutSubviews() {
super.layoutSubviews()
self.makeRound()
}
Is it possible to have multiple Texture nodes inside one container?
For example, I need to have an ASTableNode on the top half of a screen, and an ASDisplayNode with a UIView block underneath that.
I have tried using an ASViewController with a layoutSpecThatFits which returns an ASSTackLayoutSpec - but neither of the subnodes appear on the view.
Thank you!
Yes, it is possible to place both the ASTableNode and ASDisplayNode in the same stack. Use a horizontal stack layout, set the nodes flexGrow property to equal values (so they grow equally) and set automaticallyManagesSubnodes to true on your node.
override init() {
///Initialize nodes if not initialized on declaration
super.init()
automaticallyManagesSubnodes = true
}
override func layoutSpecThatFits(constrainedSize: ASSizeRange) -> ASLayoutSpec {
let stack = ASStackLayoutSpec.vertical()
stack.children = [tableNode, displayNode]
tableNode.style.flexGrow = 1
displayNode.style.flexGrow = 1
///For testing
displayNode.backgroundColor = .red
tableNode.backgroundColor = .blue
}
As you can see in this screenshot:
The Navigation bar, buttons and the speaker image are pixeled.
I migth think that it has a connection to the View Hierarchy - this View is on top of the main View (The main view label and buttons looks good and not pixeled), written in Swift:
var navUser = UIViewController()
class ViewControllerMenu: UIViewController {
navUser = storyboard!.instantiateViewController(withIdentifier: "navUser")
addChildViewController(navUser)
navUser.view.frame = view.frame
view.addSubview(navUser.view)
navUser.didMove(toParentViewController: self)
navUser.view.alpha = 0
navUser.view.layer.shadowColor = UIColor.black.cgColor
navUser.view.layer.shadowOpacity = 1
navUser.view.layer.shadowOffset = CGSize.zero
navUser.view.layer.shadowRadius = 10
navUser.view.layer.shadowPath = UIBezierPath(rect: navUser.view.bounds).cgPath
navUser.view.layer.shouldRasterize = true
}
I'm adding the View Hierarchy of this view:
This happens in all the Xcode iPhone simulators and in my personal iPhone 7.
This seems to be an odd usage of .shouldRasterize ... that is normally used when re-displaying a complex view / layer multiple times (such as game animation).
Removing that line - navUser.view.layer.shouldRasterize = true - should fix the problem.
i'm trying to add a sublayer behind the imageView however the issue is that since it is using constraints it can't seem to figure out the position and just places sublayer in left corner? i've tried to add the LFTPulseAnimation to viewDidLayoutSubViews but then everytime i reopen the app it will add one on top.
viewDidLoad
//GroupProfile ImageView
imageGroupProfile = UIImageView(frame: CGRect.zero)
imageGroupProfile.backgroundColor = UIColor.white
imageGroupProfile.clipsToBounds = true
imageGroupProfile.layer.cornerRadius = 50
self.view.addSubview(imageGroupProfile)
imageGroupProfile.snp.makeConstraints { (make) -> Void in
make.height.equalTo(100)
make.width.equalTo(100)
make.centerX.equalTo(self.view.snp.centerX)
make.centerY.equalTo(self.view.snp.centerY).offset(-40)
}
let pulseEffect = LFTPulseAnimation(repeatCount: Float.infinity, radius:160, position:imageGroupProfile.center)
self.view.layer.insertSublayer(pulseEffect, below: imageGroupProfile.layer)
i've tried to add the LFTPulseAnimation to viewDidLayoutSubViews but then everytime i reopen the app it will add one on top.
Nevertheless that is the way to do it. Just add a Bool property so that your implementation of viewDidLayoutSubViews inserts the layer only once:
var didLayout = false
override func viewDidLayoutSubviews() {
if !didLayout {
didLayout = true
// lay out that layer here
}
}
The reason is that you don't have the needed dimensions until after viewDidLayoutSubviews tells you that (wait for it) your view has been laid out! But, as you rightly say, it can be called many times subsequently, so you also add the condition so that your code runs just once, namely the first time viewDidLayoutSubviews is called.