IOS, Swift: creating a split screen with 2 views, with animation - ios

I'm an absolute IOS newbie studying Swift.
I'm trying to create an app with a calendar UI control on top (already got that working), and a listview on the bottom.
Exactly like the picture on the bottom (and I apologise for the huge pic).
Now, like the calendar app, the screen will only show the calendar control, but if you click a button - the listview will reveal itself on the bottom and the screen will become split.
The only way I can think of doing this is to generate the UITableView in code, assigning the current ViewController as both delegate and datasource, and animating both the views (calendar and listview) to grow/shrink to split the screen.
I don't want to use StackView because that's IOS-9 and up.
Is there a better way to do this?

I suspect you're trying to do something like this. Hope it helps:
Swift 2:
let view2 = UIView()
var screenWidth = CGFloat()
var screenHeight = CGFloat()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let screenSize: CGRect = UIScreen.mainScreen().bounds
screenWidth = screenSize.width
screenHeight = screenSize.height
let view1 = UIView()
view1.frame = CGRectMake(0, 0, screenWidth, screenWidth)
view1.backgroundColor = UIColor.blueColor().colorWithAlphaComponent(0.5)
self.view.addSubview(view1)
let lbl1 = UILabel()
lbl1.frame = CGRectMake(0, 0, screenWidth, 50)
lbl1.text = "This is view 1"
lbl1.textAlignment = NSTextAlignment.Center
lbl1.center = view1.center
view1.addSubview(lbl1)
let btn = UIButton()
btn.frame = CGRectMake(0,0,200,100)
btn.center = CGPoint(x: view1.center.x, y: view1.center.y+60)
btn.setTitle("Show view 2", forState: .Normal)
btn.addTarget(self, action: "showView2:", forControlEvents: .TouchUpInside)
view1.addSubview(btn)
view2.frame = CGRectMake(0, screenHeight, screenWidth, screenHeight-screenWidth)
view2.backgroundColor = UIColor.redColor().colorWithAlphaComponent(0.5)
self.view.addSubview(view2)
let lbl2 = UILabel()
lbl2.frame = CGRectMake(0, (screenHeight-screenWidth)/2-25, screenWidth, 50)
lbl2.text = "This is view 2"
lbl2.textAlignment = NSTextAlignment.Center
view2.addSubview(lbl2)
}
var c = 0
func showView2(sender : UIButton) {
UIView.animateWithDuration(1.0, delay: 0.0, options: .CurveEaseOut, animations: {
if (self.c%2 == 0) {
self.view2.frame = CGRectMake(0, self.screenWidth, self.screenWidth, self.screenHeight-self.screenWidth)
sender.setTitle("Hide view 2", forState: .Normal)
}
else {
self.view2.frame = CGRectMake(0, self.screenHeight, self.screenWidth, self.screenHeight-self.screenWidth)
sender.setTitle("Show view 2", forState: .Normal)
}
}, completion: { finished in
})
c++
}
Swift 3:
let view2 = UIView()
var screenWidth = CGFloat()
var screenHeight = CGFloat()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let screenSize: CGRect = UIScreen.main.bounds
screenWidth = screenSize.width
screenHeight = screenSize.height
let view1 = UIView()
view1.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenWidth)
view1.backgroundColor = UIColor.blue.withAlphaComponent(0.5)
self.view.addSubview(view1)
let lbl1 = UILabel()
lbl1.frame = CGRect(x: 0, y: 0, width: screenWidth, height: 50)
lbl1.text = "This is view 1"
lbl1.textAlignment = NSTextAlignment.center
lbl1.center = view1.center
view1.addSubview(lbl1)
let btn = UIButton()
btn.frame = CGRect(x: 0, y: 0, width: 200, height: 100)
btn.center = CGPoint(x: view1.center.x, y: view1.center.y+60)
btn.setTitle("Show view 2", for: .normal)
btn.addTarget(self, action: #selector(showView2(_:)), for: .touchUpInside)
view1.addSubview(btn)
view2.frame = CGRect(x: 0, y: screenHeight, width: screenWidth, height: screenHeight-screenWidth)
view2.backgroundColor = UIColor.red.withAlphaComponent(0.5)
self.view.addSubview(view2)
let lbl2 = UILabel()
lbl2.frame = CGRect(x: 0, y: (screenHeight-screenWidth)/2-25, width: screenWidth, height: 50)
lbl2.text = "This is view 2"
lbl2.textAlignment = NSTextAlignment.center
view2.addSubview(lbl2)
}
var c = 0
func showView2(_ sender : UIButton) {
UIView.animate(withDuration: 1.0, delay: 0.0, options: .curveEaseOut, animations: {
if (self.c%2 == 0) {
self.view2.frame = CGRect(x: 0, y: self.screenWidth, width: self.screenWidth, height: self.screenHeight-self.screenWidth)
sender.setTitle("Hide view 2", for: .normal)
}
else {
self.view2.frame = CGRect(x: 0, y: self.screenHeight, width: self.screenWidth, height: self.screenHeight-self.screenWidth)
sender.setTitle("Show view 2", for: .normal)
}
}, completion: { finished in
})
c += 1
}

Related

How to change the postion of the title after changing the height of Navigation Bar in Xcode

I want to change the position of the image title of the navigation bar after changing the height of navigation, but it doesn't work. I'm a rookie,please help me, thank you guys!
override func viewDidAppear(_ animated: Bool)
{
NavigationBarHeight()
}
func NavigationBarHeight() {
for subview in (self.navigationController?.navigationBar.subviews)! {
if NSStringFromClass(subview.classForCoder).contains("BarBackground") {
var subViewFrame: CGRect = subview.frame
subViewFrame.size.height = 75
subview.frame = subViewFrame
}
}
}
func addNavBarImage() {
let navController = navigationController
let image = UIImage(named: "文字logo")
let imageView = UIImageView(image: image)
let bannerWidth = navController?.navigationBar.frame.size.width
let bannerHeight = navController?.navigationBar.frame.size.height
let bannerX = bannerWidth! / 2 - image!.size.width / 2
let bannerY = bannerHeight! / 2 - image!.size.height / 2
imageView.frame = CGRect(x: bannerX, y: bannerY, width: bannerWidth!/2, height: bannerHeight! / 2)
imageView.contentMode = .scaleAspectFit
navigationItem.titleView = imageView
}
Well you can use this to change :-
func title_Logo() {
let imageView = UIImageView(image: #imageLiteral(resourceName: "icon-logo"))
imageView.frame = CGRect(x: 0, y: 0, width: 170, height: 30)
imageView.contentMode = .scaleAspectFit
let titleView = UIView(frame: CGRect(x: 0, y: 0, width: 170, height: 30))
titleView.addSubview(imageView)
titleView.backgroundColor = .clear
self.navigationItem.titleView = titleView
}
and just call the function where you want to use

Custom titleView changes location after push and pop new screen in stack

I'm trying to implement custom titleView for navigation controller with "title" and "description" labels. If I placed this titleView on first VC, it looks good. If I push second VC into navigation stack and pop it, location of the titleView is changed.
titleView's constraints:
titleLabel.translatesAutoresizingMaskIntoConstraints = false
descriptionLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.widthAnchor.constraint(equalTo: widthAnchor).isActive = true
descriptionLabel.widthAnchor.constraint(equalTo: titleLabel.widthAnchor).isActive = true
titleLabel.topAnchor.constraint(equalTo: topAnchor).isActive = true
descriptionLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 2.0).isActive = true
In viewDidLoad of VC I use follow code to insert titleView:
navigationItem.titleView = BarTitleView()
navigationItem.titleView?.bounds = CGRect(x: 0, y: 0, width: view.bounds.width, height: 44)
navigationItem.titleView?.updateConstraints()
I tried to insert follow lines into viewWillAppear (second VC has different bar buttons and it can be root of problem), but nothing changes
navigationItem.titleView?.bounds = CGRect(x: 0, y: 0, width: view.bounds.width, height: 44)
navigationItem.titleView?.updateConstraints()
How can I fixed this issue?
I have created a Title and Subtitle in the Navigation bar without the need for Interface Builder and constraint modification.
My Function to create the title view looks as follows:
class func setTitle(title:String, subtitle:String) -> UIView {
let titleLabel = UILabel(frame: CGRect(x: 0, y: -8, width: 0, height: 0))
titleLabel.backgroundColor = UIColor.clear
titleLabel.textColor = UIColor.white
titleLabel.font = UIFont.boldSystemFont(ofSize: 17)
titleLabel.text = title
titleLabel.sizeToFit()
let subtitleLabel = UILabel(frame: CGRect(x: 0, y: 12, width: 0, height: 0))
subtitleLabel.backgroundColor = UIColor.clear
subtitleLabel.textColor = UIColor.white
subtitleLabel.font = UIFont.systemFont(ofSize: 12)
subtitleLabel.text = subtitle
subtitleLabel.sizeToFit()
// Fix incorrect width bug
if (subtitleLabel.frame.size.width > titleLabel.frame.size.width) {
var titleFrame = titleLabel.frame
titleFrame.size.width = subtitleLabel.frame.size.width
titleLabel.frame = titleFrame
titleLabel.textAlignment = .center
}
let titleView = UIView(frame: CGRect(x: 0, y: 0, width: titleLabel.frame.size.width, height: titleLabel.frame.size.height))
titleView.addSubview(titleLabel)
titleView.addSubview(subtitleLabel)
let widthDiff = subtitleLabel.frame.size.width - titleLabel.frame.size.width
if widthDiff < 0 {
let newX = widthDiff / 2
subtitleLabel.frame.origin.x = abs(newX)
} else {
let newX = widthDiff / 2
titleLabel.frame.origin.x = newX
}
return titleView
}
Then to use the title view in any view controller I just call this line:
self.navigationItem.titleView = Functions.Views.setTitle(title: "Title String", subtitle: "Subtitle String")

in Swift4, replacement of navigationItem.leftBarButtonItem resizes unwanted

Having a problem with UIBarButtonItem resizing when returning to VC with different values for frame and image.
var selectedR = 1
var leftFrame = CGRect()
var leftImage = UIImage()
override func viewDidLoad() {
super.viewDidLoad()
if selectedR == 0
{
leftFrame = CGRect(x: 0, y: 0, width: 33, height: 33)
leftImage = UIImage(named: “pic-0”)!
}
else if selectedR == 1
{
leftFrame = CGRect(x: 0, y: 0, width: 79, height: 33)
leftImage = UIImage(named: "pic-1")!
}
else if selectedR == 2
{
leftFrame = CGRect(x: 0, y: 0, width: 34, height: 33)
leftImage = UIImage(named: "pic-2”)!
}
let cButton = UIButton(frame: leftFrame)
cButton.setImage(leftImage, for: UIControlState())
cButton.addTarget(self.revealViewController(), action: #selector(SWRevealViewController.revealToggle(_:)), for: .touchUpInside)
cButton.contentMode = UIViewContentMode.scaleAspectFit
let leftItem = UIBarButtonItem(customView: cButton)
self.navigationItem.leftBarButtonItem = leftItem
}
First time perfect size for selectedR = 1
Coming back into viewDidLoad with different selectedR value and image blows up, distorts and setting the leftFrame size is not honoured.
This all worked perfect in swift 3, but swift 4 it goes all over the place. Any help or suggestions would be much appreciated.
One major change between iOS 10 and 11 is now bar button items are laid out by the auto layout engine. Typically that should be backward compatible. But if you are having problems with laying out bar button items, you should try setting constraints and see if that solves your problem.
In you case you would say:
var selectedR = 1
var leftFrame = CGRect()
var leftImage = UIImage()
override func viewDidLoad() {
super.viewDidLoad()
if selectedR == 0
{
leftFrame = CGRect(x: 0, y: 0, width: 33, height: 33)
leftImage = UIImage(named: “pic-0”)!
}
else if selectedR == 1
{
leftFrame = CGRect(x: 0, y: 0, width: 79, height: 33)
leftImage = UIImage(named: "pic-1")!
}
else if selectedR == 2
{
leftFrame = CGRect(x: 0, y: 0, width: 34, height: 33)
leftImage = UIImage(named: "pic-2”)!
}
let cButton = UIButton(frame: leftFrame)
cButton.widthAnchor.constraint(equalToConstant: leftFrame.width).isActive = true
cButton.heightAnchor.constraint(equalToConstant: leftFrame.height).isActive = true
cButton.setImage(leftImage, for: UIControlState())
cButton.addTarget(self.revealViewController(), action: #selector(SWRevealViewController.revealToggle(_:)), for: .touchUpInside)
cButton.contentMode = UIViewContentMode.scaleAspectFit
let leftItem = UIBarButtonItem(customView: cButton)
self.navigationItem.leftBarButtonItem = leftItem
}
This was covered in Apple's WWDC 2017 session Updating Your App for iOS 11.

How to add multiple button in a scrollView programmatically

I am trying to put multiple buttons in a scrollView but it just scrolls background view.
class HomeVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "Home"
let scrollView = UIScrollView()
let view = UIView()
scrollView.frame = self.view.bounds
self.view.backgroundColor = .green
scrollView.backgroundColor = .blue
scrollView.addSubview(view)
self.view.addSubview(scrollView)
scrollView.isPagingEnabled = true
scrollView.contentSize = CGSize(width: self.view.frame.size.width, height: self.view.frame.size.height * 3)
view.frame = CGRect(x: 0, y: self.view.frame.size.height, width: self.view.frame.size.width, height: self.view.frame.size.height)
view.backgroundColor = .yellow
attractivePlaceButtonSetup()
eatDrinkButtonSetup()
ShoppingButtonSetup()
festivalEventButtonSetup()
hotelGuestHouseButtonSetup()
travellerEssentialButtonSetup()
dealButtonSetup()
seeDoButtonSetup()
}
I wrote this code for button frame
func eatDrinkButtonSetup(){
let button = UIButton()
button.frame = CGRect(x: 5, y: 225, width: self.view.frame.size.width - 10, height: 150)
button.setTitle("Eat & Drink", for: .normal)
button.setBackgroundImage(#imageLiteral(resourceName: "imageName"), for: .normal)
button.titleEdgeInsets = UIEdgeInsets(top: -120, left: -200, bottom: 0, right: 0)
button.addTarget(self, action: #selector(targetEatDrink), for: .touchUpInside)
view.addSubview(button)
}
}
I also try to such way but it just scroll a button.
scrollView.addSubview(attractivePlaceButtonSetup)
self.view.addSubview(scrollView)
//Try this...
//Background Scroll Creation
var stickersScrollViewCount = 0
func stickersScrollContents() {
var xCoord: CGFloat = 5
let yCoord: CGFloat = 5
let buttonWidth:CGFloat = 45.0
let buttonHeight: CGFloat = 45.0
let gapBetweenButtons: CGFloat = 5
for i in 0..<stickersImageArray.count{
stickersScrollViewCount = i
// Button properties
let filterButton = UIButton(type: .custom)
filterButton.frame = CGRect(x: xCoord, y: yCoord, width: buttonWidth, height: buttonHeight)
filterButton.tag = stickersScrollViewCount
filterButton.backgroundColor = UIColor.clear
filterButton.setTitleColor(UIColor.white, for: .normal)
filterButton.titleLabel?.adjustsFontSizeToFitWidth = true
filterButton.showsTouchWhenHighlighted = true
let myimage = UIImage(named: stickersImageArray[stickersScrollViewCount])
filterButton.setImage(myimage, for: .normal)
filterButton.addTarget(self, action:#selector(StickersActionTapped), for: .touchUpInside)
filterButton.layer.cornerRadius = 5
filterButton.clipsToBounds = true
xCoord += buttonWidth + gapBetweenButtons
bgScrollView.addSubview(filterButton)
}
bgScrollView.contentSize = CGSize(width: buttonWidth * CGFloat(stickersScrollViewCount+2), height: yCoord)
}
//Call the function where ever you want viewDidLoad() or on Button Click!!
//Hope this helps!!!

App crashes due to use a custom view with images on different view

My app is working fine with all iOS simulator above iOS v7.0 and also working on most of device but its crash into iPod touch iOS 8.4. I am not able to identify what was the issue with my app, because when I connect this device with Xcode 6.3 and test my app then its working fine.
So my app crash into iPod touch iOS V8.4 in two different cases:
Download app from Test fairy into device and open screen on which I
am using my custom view
Connect device with Xcode and run app into device(With connected
device app work fine even on screen where I used my custom view).
Then disconnect device, Run app again but this time my app was crash
when I reach on screen with custom view.
Custom view code :
import UIKit
class OutfitView:UIView {
var screenSize = SCREEN_SIZE()
let bigScaleImageView: UIImageView!
let rigthSideImageOne: UIImageView!
let rigthSideImageTwo: UIImageView!
let rigthSideImageThree: UIImageView!
let oufitNameLbl: UILabel!
let oufitItemCountLbl: UILabel!
let likeBtn: UIButton!
let likeCountBtn: UIButton!
let rigthSideFooterLbl:UILabel!
let moreImageLbl: UILabel!
override init(frame: CGRect ) {
var yposition = CGFloat(0)
oufitNameLbl = UILabel(frame: CGRect(x: 0, y: yposition, width: (screenSize.width - 20) * (70/100), height: 30))
oufitNameLbl.text = "Outfit Name"
oufitNameLbl.textAlignment = .Left
oufitNameLbl.textColor = UIColor.blackColor()
oufitNameLbl.font = UIFont.systemFontOfSize(18)
oufitItemCountLbl = UILabel(frame: CGRect(x: oufitNameLbl.frame.width, y: yposition, width: (screenSize.width - 20) * (30/100), height: 30))
oufitItemCountLbl.text = "8 Items"
oufitItemCountLbl.textAlignment = .Right
oufitItemCountLbl.textColor = UIColor.grayColor()
oufitItemCountLbl.font = UIFont.systemFontOfSize(14)
yposition += oufitNameLbl.frame.height
var height = frame.height - 80
bigScaleImageView = UIImageView(frame: CGRect(x: 0, y: yposition, width: (screenSize.width - 20) * (70/100) - 4, height: height))
bigScaleImageView.contentMode = UIViewContentMode.ScaleAspectFit
bigScaleImageView.layer.borderWidth = 2
bigScaleImageView.layer.borderColor = UIColor.whiteColor().CGColor
bigScaleImageView.backgroundColor = UIColor.whiteColor()
rigthSideImageOne = UIImageView(frame: CGRect(x: bigScaleImageView.frame.size.width+4, y: yposition, width: (screenSize.width - 20) * (30/100), height: (height - 8)/3))
rigthSideImageOne.layer.borderWidth = 2
rigthSideImageOne.layer.borderColor = UIColor.whiteColor().CGColor
rigthSideImageOne.contentMode = UIViewContentMode.ScaleAspectFit
rigthSideImageOne.backgroundColor = UIColor.whiteColor()
rigthSideImageTwo = UIImageView(frame: CGRect(x: bigScaleImageView.frame.size.width+4, y: yposition + rigthSideImageOne.frame.height+4, width: (screenSize.width - 20) * (30/100), height: (height - 8)/3))
rigthSideImageTwo.layer.borderWidth = 2
rigthSideImageTwo.layer.borderColor = UIColor.whiteColor().CGColor
rigthSideImageTwo.contentMode = UIViewContentMode.ScaleAspectFit
rigthSideImageTwo.backgroundColor = UIColor.whiteColor()
rigthSideImageThree = UIImageView(frame: CGRect(x: bigScaleImageView.frame.size.width+4, y:yposition + (rigthSideImageOne.frame.height + rigthSideImageTwo.frame.height)+8, width: (screenSize.width - 20) * (30/100), height: (height - 8)/3))
rigthSideImageThree.layer.borderWidth = 2
rigthSideImageThree.layer.borderColor = UIColor.whiteColor().CGColor
rigthSideImageThree.contentMode = UIViewContentMode.ScaleAspectFit
rigthSideImageThree.backgroundColor = UIColor.whiteColor()
moreImageLbl = UILabel(frame: CGRect(x: bigScaleImageView.frame.size.width+4, y: yposition + (rigthSideImageOne.frame.height + rigthSideImageTwo.frame.height)+8, width: (screenSize.width - 20) * (30/100), height: (height - 8)/3))
moreImageLbl.text = "+4"
moreImageLbl.textAlignment = .Center
moreImageLbl.textColor = UIColor.whiteColor()
moreImageLbl.backgroundColor = Utilities.getGSBlackColor(alphaValue: CGFloat(0.6))
yposition += bigScaleImageView.frame.height
let editLikeView = UIView(frame: CGRect(x: 0, y: yposition, width: screenSize.width - 20, height: 50))
likeBtn = UIButton(frame: CGRect(x: 0, y: 8, width: 15, height: 15))
likeBtn.setTitle("", forState: .Normal)
likeBtn.setTitle("", forState: .Selected)
//likeBtn.backgroundColor = UIColor.whiteColor()
var image = UIImage(named: "gray_heart")?.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
likeBtn.setImage(image, forState: .Normal)
likeBtn.setTitleColor(UIColor.whiteColor(), forState: .Normal)
likeBtn.setTitleColor(Utilities.getGSRedColor(), forState: .Selected)
likeBtn.titleLabel?.font = UIFont.systemFontOfSize(14)
likeBtn.titleLabel?.textAlignment = .Left
likeBtn.userInteractionEnabled = true
editLikeView.addSubview(likeBtn)
likeCountBtn = UIButton(frame: CGRect(x: 13, y: 0, width: 30, height: 30))
likeCountBtn.setTitle("28", forState: .Normal)
likeCountBtn.setTitle("28", forState: .Selected)
likeCountBtn.setTitleColor(Utilities.getMasterColor(), forState: .Normal)
likeCountBtn.setTitleColor(Utilities.getMasterColor(), forState: .Selected)
likeCountBtn.titleLabel?.font = UIFont.systemFontOfSize(14)
likeCountBtn.titleLabel?.textAlignment = .Left
likeCountBtn.userInteractionEnabled = true
editLikeView.addSubview(likeCountBtn)
rigthSideFooterLbl = UILabel(frame: CGRect(x: (screenSize.width-20) - ((screenSize.width - 20) * (0.80)), y: 0, width:(screenSize.width - 20) * (0.80), height: 30) )
rigthSideFooterLbl.text = "CreatedBy:#XXXXXXXXX"
rigthSideFooterLbl.textAlignment = .Right
rigthSideFooterLbl.textColor = UIColor.blackColor()
rigthSideFooterLbl.font = UIFont.systemFontOfSize(16)
editLikeView.addSubview(rigthSideFooterLbl)
super.init(frame: frame)
self.addSubview(oufitNameLbl)
self.addSubview(oufitItemCountLbl)
self.addSubview(editLikeView)
self.addSubview(bigScaleImageView)
self.addSubview(rigthSideImageOne)
self.addSubview(rigthSideImageTwo)
self.addSubview(rigthSideImageThree)
self.addSubview(moreImageLbl)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
And code where I used my custom view:
for i in 1...3{
var outfitView = OutfitView(frame: CGRect(x: 10, y: yposition, width: screenSize.width - 20, height: 330))
outfitView.bigScaleImageView.image = image1
outfitView.rigthSideImageOne.image = image2
outfitView.rigthSideImageTwo.image = image3
outfitView.rigthSideImageThree.image = image4
itemDetailView.frame.size.height += (outfitView.frame.height + 10 )
yposition += outfitView.frame.height + 10
itemDetailView.addSubview(outfitView)
}

Resources