UIView unable to get transparent property - ios

I am trying to add a subview to the window (for using it as side menu). It has a child view which is transparent view. However I am unable to get the transparent property when it runs in simulator.
I am using the following code:
override func viewWillAppear(_ animated: Bool) {
frame = CGRect(x: 0, y:0, width:0, height:0)
frame.size.height = UIScreen.main.bounds.height
frame.size.width = UIScreen.main.bounds.width
sideMenuView.frame = frame
sideMenuTransparentView.isOpaque = false
sideMenuTransparentView.backgroundColor = UIColor.gray.withAlphaComponent(0.5)
UIApplication.shared.keyWindow?.addSubview(sideMenuView)
}
However I am seeing no effect of this to make the view as transparent. What's possibly wrong here and how should I proceed rectifying this?
The weird thing here is that when I replace the lines
sideMenuTransparentView.isOpaque = false
sideMenuTransparentView.backgroundColor = UIColor.gray.withAlphaComponent(0.5)
with
sideMenuView.isOpaque = false
sideMenuView.backgroundColor = UIColor.gray.withAlphaComponent(0.5)
I can see the effect. I am unable to understand what's going in here and how should I correct this.

You seem to have forgotten to add the transparent view to the main sideMenuView.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) // You need to call super when overriding
frame = CGRect(x: 0, y:0, width:0, height:0)
frame.size.height = UIScreen.main.bounds.height
frame.size.width = UIScreen.main.bounds.width
sideMenuView.frame = frame
sideMenuTransaparentView.frame = yourFrame // required frame
sideMenuTransparentView.isOpaque = false
sideMenuTransparentView.backgroundColor = UIColor.gray.withAlphaComponent(0.5) // 100% transparency
sideMenuView.addSubview(view: sideMenuTransparentView)
UIApplication.shared.keyWindow?.addSubview(sideMenuView)
}
Also, you forgot to call super.

Related

How can I fill image in scroll view to fill screen?

I am playing around with scroll views, and I've run into an issue I'be stuck with. I have a view controller create in Storyboard. The view controller contains a scroll view which fills the entire superview.
I then added the images programmatically to the scroll view. The images do show within the scroll view and paging works just fine. Only problem is the scroll view is set ti fill superview but the image view that hold the images seems like it stops above where the navigation bar would be. How can I have the image view fill the whole view within the scroll view?
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var pagingView: UIPageControl!
var images = [UIImage]()
var frame = CGRect(x: 0, y: 0,width: 0,height: 0)
override func viewDidLoad() {
super.viewDidLoad()
scrollView.delegate = self
scrollView.isPagingEnabled = true
images = [UIImage(named: "Slide1")!, UIImage(named: "Slide2")!, UIImage(named: "Slide3")!, UIImage(named: "Slide4")!]
pagingView.numberOfPages = images.count
// This is where I think I'm having the height problem.
for i in 0..<images.count {
let imageView = UIImageView()
let x = self.view.frame.size.width * CGFloat(i)
imageView.frame = CGRect(x: x, y: 0, width: self.view.frame.width, height: self.view.frame.height)
imageView.contentMode = .scaleAspectFill
imageView.image = images[i]
scrollView.contentSize.width = scrollView.frame.size.width * CGFloat(i + 1)
scrollView.addSubview(imageView)
}
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let pageNumber = scrollView.contentOffset.x / scrollView.frame.size.width
pagingView.currentPage = Int(pageNumber)
}
After setting nav bar to hidden, here is the output
Scroll view background color is red
In this case you need to enable the parent view clipsToBounds. Set UIScrollview clipsToBounds property to True.
Programmatically scrollView.clipsToBounds = true
In UIStoryBoard - Click the view->Attributes Inspector
If you would like to see the whole screen, make sure to add the topConstraint of scrollView assigned superView and hide the navigationBar in viewWillAppear,
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(true, animated: animated)
}
Make sure to remove the status bar by
override var prefersStatusBarHidden: Bool {
return true
}
Update the Y position of Image.
imageView.frame = CGRect(x: x, y: **self.scrollView.frame.minY**, width: self.view.frame.width, height: self.view.frame.height)
Update the scrollView topConstraint by -20.

UIScrollView pages content not working properly - iOS

I've been trying for one whole day to make it work right. I tried different tutos and made adjustments (searching in here) but it doesnt work properly.
On iphone 5s, it almost works right, excepts for the last page that it seems to add "half" of a page on scroll view. The green part is the background color of the scroll view and it doesn't bounce back.
On iphone 6, the content is all messed up and instead of having 5 images, it has only 4 and a half (i cant scroll it anymore and it doesn't bounce back).
If I press continue, it works perfectly on both screen sizes. It is only the swipe option that is not working properly.
Here is the code where I put the images inside the scroll view.
func loadContent() {
var frame = CGRect(x: 0, y: 0, width: 0, height: 0)
for i in 0..<imageArr.count { // is 5
frame.origin.x = scrollView.frame.size.width * CGFloat(i)
frame.size = self.scrollView.frame.size
let imageView = UIImageView(frame: frame)
let image = UIImage(named: imageArr[i])
imageView.autoresizingMask = [.flexibleWidth, .flexibleHeight, .flexibleBottomMargin, .flexibleRightMargin, .flexibleLeftMargin, .flexibleTopMargin]
imageView.contentMode = .scaleAspectFit
imageView.clipsToBounds = true
imageView.backgroundColor = UIColor.red
imageView.image = image
scrollView.addSubview(imageView)
self.scrollView.contentSize.width = self.scrollView.frame.width * CGFloat(i)
}
}
///Function of Continue button
#IBAction func nextImage(_ sender: Any) {
UIView.animate(withDuration: 0.3) {
self.scrollView.contentOffset.x = self.scrollView.frame.width * CGFloat(self.pageControl.currentPage+1)
}
}
I've been searching for 4 hours for a solution but nothing seems to work.
[Edit]: With the answer of TheFuquan I could solve the problem.
[Obs:] if you searching about the messed content, these lines of code can help you. All the tutos that I saw didn't have these lines and the content just wouldnt align perfect and this solved:
imageView.autoresizingMask = [.flexibleWidth, .flexibleHeight, .flexibleBottomMargin, .flexibleRightMargin, .flexibleLeftMargin, .flexibleTopMargin]
imageView.contentMode = .scaleAspectFit
imageView.clipsToBounds = true
Why is the following line in your for loop:
self.scrollView.contentSize.width = self.scrollView.frame.width * CGFloat(i)
You should do this before the for loop like this:
self.scrollView.contentSize.width = self.scrollView.frame.width * imageArr.count
this is a typical problem that i face each time i try to load some dynamic content inside a view.
If you re calling your function loadContent from viewDidLoad, then you should call your loadContent inside viewDidLayoutSubviews
Be aware that unlike viewDidLoad, viewDidLayoutSubviews may get called multiple times, so have a flag to ensure that your loadContent gets invoked only once.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
guard self.didLoadContent == false else {
return
}
self.didLoadContent = true
loadContent()
}
this way you let the view loaded from your storyboard to resize the iPhone's size.

childViewController.view.frame in UIView present different value

I use childViewController to separate view in project, but some strange issue happened, here is my code.
class ViewController: UIViewController {
var container = UIView()
var childVC = ChildViewController()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
addChildViewController(childVC)
childVC.didMove(toParentViewController: self)
addChildView()
setContainerFrame()
}
func setContainerFrame() {
container.frame = CGRect(x: 0, y: 100, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height - 100)
container.backgroundColor = .red
view.addSubview(container)
}
func addChildView() {
let frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
childVC.view.frame = frame
childVC.view.backgroundColor = .green
container.addSubview(childVC.view)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("childVC.view.frame: \(childVC.view.frame)")
}
}
class ChildViewController: UIViewController {
}
when I exchange the order invoking func addChildView() and func setContainerFrame() in ViewController's viewDidLoad(), xcode'console prints different frame log.
This is due to the autoresizingMask of the childVC.view. By default this is set to have flexible width and height. So if you set the frame of the container and then the frame of the childVC.view then you get the actual value you set but if you reverse it and set the frame of the childVC.view and then the container the frame of the childVC.view is automatically updated to have the same relative width and height.
For example if the frame size for the container was 100 x 100 and then you change it to 200 x 200 the frame size for childVC.view will be doubled.
To remove this set the childVC.view.autoresizingMask = [] so it remains as you set it.
The strange behavior occurs because in addChildView() function you are adding the child view controller's view as subview to container view but container view's frame is setting in the function setContainerFrame() which is not yet called. That means you are adding a subview to a view whose frame hasn't set already.

How to embed stack view in scroll view programmatically

I have tried embedding it, but my stack view is dynamic and my app is also changing orientations time to time. I have segment control at the end of the view.
I have also tried googling it but had no luck. thanks in advance.
So far I have done:
In view did load:
mainStackView.axis = UILayoutConstraintAxis.Vertical
mainStackView.spacing = 3
scrollView.frame = self.view.bounds
scrollView.addSubview(mainStackView)
view.addSubview(scrollView)
In view did layout:
override func viewDidLayoutSubviews()
{
super.viewDidLayoutSubviews()
let top = topLayoutGuide.length
let bottom = bottomLayoutGuide.length
self.mainStackView.frame = CGRect(x: 0, y: top, width: view.frame.width, height: view.frame.height - top - bottom).insetBy(dx: 10, dy: 10)
dispatch_async(dispatch_get_main_queue())
{
self.scrollView.frame = self.view.bounds
self.scrollView.contentSize = CGSize(width: self.view.bounds.width, height: self.segmentedControl.frame.origin.y + self.segmentedControl.frame.height + 50)
}
print(scrollView.contentSize)
}
You need to set the height constraint of segment control.
For Example:
segmentedControl.heightAnchor.constraintEqualToConstant(50).active = true
More over, you can Add Empty bottom view to avoid stack view's must fill mechanism. This will show you desired view output.
var bottomView = UIView(frame: CGRectZero)
stackView.addArrangedSubview(bottomView)

Embedding UINavigationController in scrollView

I'm trying to do an application with 3 startup views, which you can swipe between. Pretty much Snapchat like.
I've got this going pretty well, but when I try to embed one of the 3 View Controller, it gets resized to a small part of the screen.
Here's my code:
override func viewDidLoad() {
super.viewDidLoad()
let accCtrl = AccountViewController()
let feedCtrl = UINavigationController(rootViewController: HomeViewController())
let hashsCtrl = AccountViewController()
self.addChildViewController(hashsCtrl)
self.scrollView!.addSubview(hashsCtrl.view)
hashsCtrl.didMoveToParentViewController(self)
self.addChildViewController(feedCtrl)
self.scrollView!.addSubview(feedCtrl.view)
feedCtrl.didMoveToParentViewController(self)
self.addChildViewController(accCtrl)
self.scrollView!.addSubview(accCtrl.view)
accCtrl.didMoveToParentViewController(self)
accCtrl.view.frame = view.frame
// feedCtrl.view.autoresizesSubviews = false
feedCtrl.view.frame = CGRectMake(view.frame.width, 0, view.frame.width, view.frame.height)
feedCtrl.setNavigationBarHidden(true, animated: false)
feedCtrl.view.setNeedsLayout()
hashsCtrl.view.frame = CGRectMake(view.frame.width * 2, 0, view.frame.width, view.frame.height)
scrollView.contentSize = CGSizeMake(view.frame.width * 3, view.frame.height)
scrollView.pagingEnabled = true
scrollView.showsHorizontalScrollIndicator = false
scrollView.showsVerticalScrollIndicator = false
scrollView.contentOffset = CGPointMake(view.frame.width, 0)
}
I've noticed that the resulting width of the view on-screen is pretty much x - 280. If I set the feedCtrl.view.frame to a width, the resulting width is 1.0 point. As it is actually - aka the screen width -, it results in a 40.0 point width.
I've also noticed that if I uncomment the line where I put the feedCtrl.view.autoresizeSubviews boolean to false, the width on-screen is correct, but I can't get user-interaction on the view.
Any ideas ?
I had a similar problem. In viewDidLoad, try to add (that worked for me):
self.ScrollView.frame = (UIApplication.sharedApplication().delegate?.window!.frame)!

Resources