second vc is smaller that the initial vc - swift

I got this problem on iPad after update yesterday: if I load the second view controller, it appears smaller that the initial one (see photos below). Interesting, that is happening only since my update to the new iOS on iPad. There is no such problem on iPhone: the both VCs have there the same size.
Here is the code:
import UIKit
class StartVC: UIViewController, ButtonDelegate {
var width = CGFloat()
var height = CGFloat()
override func viewDidLoad() {
super.viewDidLoad()
width = view.frame.width
height = view.frame.height
setTestBtn()
view.backgroundColor = UIColor.purple
}
func setTestBtn(){
let a = Button(frame: CGRect(x: 0,y: 0, width: width*0.2, height: width*0.2))
a.center = CGPoint(x: width*0.5, y: height*0.5)
a.backgroundColor = .cyan
a.delegate = self
a.setLabel()
a.label.text = "Go to the MainVC"
view.addSubview(a)
}
func buttonClicked(sender: Button) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "mainVC") as! MainVC
let transition = CATransition()
transition.duration = 2
transition.type = CATransitionType.push
transition.subtype = CATransitionSubtype.fromRight
view.window!.layer.add(transition, forKey: kCATransition)
vc.view.frame = view.bounds
self.present(vc, animated: true, completion: nil)
print("# ViewController func buttonClicked() OK!")
}
import UIKit
class MainVC: UIViewController, ButtonDelegate {
var width = CGFloat()
var height = CGFloat()
override func viewDidLoad() {
super.viewDidLoad()
width = view.frame.width
height = view.frame.height
setTestBtn()
view.backgroundColor = .red
}
func setTestBtn(){
let a = Button(frame: CGRect(x: 0,y: 0, width: width*0.2, height: width*0.2))
a.center = CGPoint(x: width*0.5, y: height*0.5)
a.backgroundColor = .orange
a.delegate = self
a.setLabel()
a.label.text = "Go to the StartVC"
view.addSubview(a)
}
func buttonClicked(sender: Button) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "startVC") as! StartVC
let transition = CATransition()
transition.duration = 2
transition.type = CATransitionType.push
transition.subtype = CATransitionSubtype.fromRight
view.window!.layer.add(transition, forKey: kCATransition)
vc.view.frame = view.bounds
self.present(vc, animated: true, completion: nil)
print("# ViewController func buttonClicked() OK!")
}
}

Since the release of iOS 13, the modal presentation style of View Controllers is chosen automatically by the system by default.
If you wish to counter this effect, this can help you.
vc.modalPresentationStyle = .overFullScreen
self.present(vc, animated: true, completion: nil)
Hope this helps!

Related

swipe between UIView with segemented control programmatically

hi fellow developer I want to swipe between uiview with scrollView while changing the the index and small indicator move left and right. but is not responding while I try to swipe. this is my picture and my setup to scroll between uiview. can you tell me where I am missing?
let segmentedControl = UISegmentedControl()
let containerView = UIView()
let indicatorView = UIView()
let leftView = UIView()
let rightView = UIView()
let scrollView = UIScrollView()
var slides = [UIView]()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
slides.append(leftView)
slides.append(rightView)
segmentedControl.insertSegment(withTitle: "Harian", at: 0, animated: true)
segmentedControl.insertSegment(withTitle: "Mata Pelajaran", at: 1, animated: true)
segmentedControl.selectedSegmentIndex = 0
segmentedControl.addTarget(self, action: #selector(handleTap), for: .valueChanged)
setupSlideScrollView()
}
func setupSlideScrollView() {
view.addSubview(scrollView)
scrollView.isPagingEnabled = true
scrollView.translatesAutoresizingMaskIntoConstraints = false
for i in 0..<slides.count {
slides[i].frame = CGRect(x: view.frame.width * CGFloat(i), y: 0, width: view.frame.width, height: view.frame.height)
scrollView.addSubview(slides[i])
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageIndex = round(scrollView.contentOffset.x / view.frame.width)
segmentedControl.selectedSegmentIndex = Int(pageIndex)
}
#objc func handleTap(_ sender: UISegmentedControl) {
indicatorView.frame.origin.x = (segmentedControl.frame.width / CGFloat(segmentedControl.numberOfSegments)) * CGFloat(segmentedControl.selectedSegmentIndex)
UIView.animate(withDuration: 0.5, animations: {
self.view.layoutIfNeeded()
self.indicatorView.transform = CGAffineTransform(scaleX: 0.7, y: 1)
}) { (finish) in
UIView.animate(withDuration: 0.4, animations: {
self.indicatorView.transform = CGAffineTransform.identity
})
}
}

How to set top left and right corner radius with desired drop shadow in UITabbar?

I've spent almost a couple of hours to figure it out. However, it did not happen and finally, I had to come here. Two things are required to be achieved:
Firstly I'd like to have a spontaneous corner radius at the top (which is basically TopRight & TopLeft) of UITabbar.
Secondly, I'd like to have a shadow above those corner radius(shown in below image).
Please have a look at below image
Let me know if anything further required from my side, I'll surely provide that.
Any help will be appreciated.
Edit 1
One more little question arose here along, suppose, Even if, However, we were able to accomplish this, Would Apple review team accept the application?
I'm being little nervous and curious about it.
Q : One more little question arose here along, suppose, Even if, However, we were able to accomplish this, Would Apple review team accept the application?
A: Yes They are accept your app I have Add This Kind Of TabBar.
Create Custom TabBar
HomeTabController
import UIKit
class HomeTabController: UITabBarController
{
var viewCustomeTab : CustomeTabView!
var lastSender : UIButton!
//MARK:- ViewController Methods
override func viewDidLoad()
{
super.viewDidLoad()
UITabBar.appearance().shadowImage = UIImage()
allocateTabItems()
}
//MARK:- Prepare Methods
// Allocate shop controller with tab bar
func allocateTabItems()
{
let vc1 = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "Avc") as? Avc
let item1 = UINavigationController(rootViewController: vc1!)
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.viewControllers = [item1]
createTabBar()
}
func createTabBar()
{
viewCustomeTab = CustomeTabView.instanceFromNib()
viewCustomeTab.translatesAutoresizingMaskIntoConstraints = false
viewCustomeTab.call()
self.view.addSubview(viewCustomeTab)
if #available(iOS 11, *)
{
let guide = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([guide.bottomAnchor.constraint(equalToSystemSpacingBelow: viewCustomeTab.bottomAnchor, multiplier: 0), viewCustomeTab.leadingAnchor.constraint(equalToSystemSpacingAfter: guide.leadingAnchor, multiplier: 0), guide.trailingAnchor.constraint(equalToSystemSpacingAfter: viewCustomeTab.trailingAnchor, multiplier: 0), viewCustomeTab.heightAnchor.constraint(equalToConstant: 70) ])
}
else
{
let standardSpacing: CGFloat = 0
NSLayoutConstraint.activate([viewCustomeTab.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor, constant: standardSpacing), bottomLayoutGuide.topAnchor.constraint(equalTo: viewCustomeTab.bottomAnchor, constant: standardSpacing)
])
}
viewCustomeTab.btnTab1.addTarget(self, action: #selector(HomeTabController.buttonTabClickAction(sender:)), for: .touchUpInside)
viewCustomeTab.btnTab2.addTarget(self, action: #selector(HomeTabController.buttonTabClickAction(sender:)), for: .touchUpInside)
viewCustomeTab.btnTab3.addTarget(self, action: #selector(HomeTabController.buttonTabClickAction(sender:)), for: .touchUpInside)
viewCustomeTab.btnTab4.addTarget(self, action: #selector(HomeTabController.buttonTabClickAction(sender:)), for: .touchUpInside)
viewCustomeTab.btnTab5.addTarget(self, action: #selector(HomeTabController.buttonTabClickAction(sender:)), for: .touchUpInside)
//self.view.layoutIfNeeded()
viewCustomeTab.layoutIfNeeded()
viewCustomeTab.btnTab1.alignContentVerticallyByCenter(offset: 3)
viewCustomeTab.btnTab2.alignContentVerticallyByCenter(offset: 3)
viewCustomeTab.btnTab3.alignContentVerticallyByCenter(offset: 3)
viewCustomeTab.btnTab4.alignContentVerticallyByCenter(offset: 3)
viewCustomeTab.btnTab5.alignContentVerticallyByCenter(offset: 3)
viewCustomeTab.btnTab1.isSelected = true
}
//MARK:- Button Click Actions
//Manage Tab From Here
func setSelect(sender:UIButton)
{
viewCustomeTab.btnTab1.isSelected = false
viewCustomeTab.btnTab2.isSelected = false
viewCustomeTab.btnTab3.isSelected = false
viewCustomeTab.btnTab4.isSelected = false
viewCustomeTab.btnTab5.isSelected = false
sender.isSelected = true
}
#objc func buttonTabClickAction(sender:UIButton)
{
//self.selectedIndex = sender.tag
if sender.tag == 0
{
let vc1 = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "Bvc") as? Bvc
let item1 = UINavigationController(rootViewController: vc1!)
item1.navigationBar.isHidden = false
self.viewControllers = [item1]
setSelect(sender: viewCustomeTab.btnTab1)
return
}
if sender.tag == 1
{
let vc2 = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "Cvc") as? Cvc
let item2 = UINavigationController(rootViewController: vc2!)
item2.navigationBar.isHidden = false
item2.navigationBar.isTranslucent = false
self.viewControllers = [item2]
setSelect(sender: viewCustomeTab.btnTab2)
return
}
if sender.tag == 2
{
let vc3 = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "Dvc") as? Dvc
let item3 = UINavigationController(rootViewController: vc3!)
item3.navigationBar.isHidden = false
item3.navigationBar.isTranslucent = false
self.viewControllers = [item3]
setSelect(sender: viewCustomeTab.btnTab3)
return
}
if sender.tag == 3
{
}
if sender.tag == 4
{
}
}
}
Create Custom View For Shadow Effect and For + Button.
import UIKit
class CustomeTabView: UIView
{
#IBOutlet weak var btnTab5: UIButton!
#IBOutlet weak var btnTab4: UIButton!
#IBOutlet weak var btnTab3: UIButton!
#IBOutlet weak var btnTab2: UIButton!
#IBOutlet weak var btnTab1: UIButton!
#IBOutlet weak var vRadius: UIView!
class func instanceFromNib() -> CustomeTabView
{
return UINib(nibName: "CustomeTabView", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! CustomeTabView
}
private var shadowLayer: CAShapeLayer!
override func layoutSubviews()
{
super.layoutSubviews()
let shadowSize : CGFloat = 2.0
let shadowPath = UIBezierPath(roundedRect: CGRect(x: -shadowSize / 2, y: -shadowSize / 2, width: self.vRadius.frame.size.width, height: self.vRadius.frame.size.height), cornerRadius : 20)
self.vRadius.layer.masksToBounds = false
self.vRadius.layer.shadowColor = UIColor.black.cgColor
self.vRadius.layer.shadowOffset = CGSize.zero//(width: self.vRadius.frame.size.width, height: self.vRadius.frame.size.height)
self.vRadius.layer.shadowOpacity = 0.5
self.vRadius.layer.shadowPath = shadowPath.cgPath
self.vRadius.layer.cornerRadius = 20
}
OpenImg
Swift 4.2
You can achieve this with some custom view with a custom tab bar controller. You can customize the colors and shadows by editing only the custom views.
Custom Tab Bar Controller
import UIKit
class MainTabBarController: UITabBarController{
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
tabBar.backgroundImage = UIImage.from(color: .clear)
tabBar.shadowImage = UIImage()
let tabbarBackgroundView = RoundShadowView(frame: tabBar.frame)
tabbarBackgroundView.cornerRadius = 25
tabbarBackgroundView.backgroundColor = .white
tabbarBackgroundView.frame = tabBar.frame
view.addSubview(tabbarBackgroundView)
let fillerView = UIView()
fillerView.frame = tabBar.frame
fillerView.roundCorners([.topLeft, .topRight], radius: 25)
fillerView.backgroundColor = .white
view.addSubview(fillerView)
view.bringSubviewToFront(tabBar)
}
Rounded Shadow View
import UIKit
class RoundShadowView: UIView {
let containerView = UIView()
override init(frame: CGRect) {
super.init(frame: frame)
layoutView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func layoutView() {
// set the shadow of the view's layer
layer.backgroundColor = UIColor.clear.cgColor
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = CGSize(width: 0, height: -8.0)
layer.shadowOpacity = 0.12
layer.shadowRadius = 10.0
containerView.layer.cornerRadius = cornerRadius
containerView.layer.masksToBounds = true
addSubview(containerView)
containerView.translatesAutoresizingMaskIntoConstraints = false
// pin the containerView to the edges to the view
containerView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
containerView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
containerView.topAnchor.constraint(equalTo: topAnchor).isActive = true
containerView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
}
}
UIImage extension
import UIKit
extension UIImage {
static func from(color: UIColor) -> UIImage {
let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(color.cgColor)
context!.fill(rect)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return img!
}
}
To add any radius or shape you can use a UIBezierPath. The example that I put has left and right corners with a radius and you can use more designable personalizations if you want.
#IBDesignable class TabBarWithCorners: UITabBar {
#IBInspectable var color: UIColor?
#IBInspectable var radii: CGFLoat = 15.0
private var shapeLayer: CALayer?
override func draw(_ rect: CGRect) {
addShape()
}
private func addShape() {
let shapeLayer = CAShapeLayer()
shapeLayer.path = createPath()
shapeLayer.strokeColor = UIColor.gray.withAlphaComponent(0.1).cgColor
shapeLayer.fillColor = color?.cgColor ?? UIColor.white.cgColor
shapeLayer.lineWidth = 1
if let oldShapeLayer = self.shapeLayer {
layer.replaceSublayer(oldShapeLayer, with: shapeLayer)
} else {
layer.insertSublayer(shapeLayer, at: 0)
}
self.shapeLayer = shapeLayer
}
private func createPath() -> CGPath {
let path = UIBezierPath(
roundedRect: bounds,
byRoundingCorners: [.topLeft, .topRight],
cornerRadii: CGSize(width: radii, height: 0.0))
return path.cgPath
}
}
Swift 5.3.1, XCode 11+, iOS 14
For using in storyboards:
import UIKit
class CustomTabBar: UITabBar {
override func awakeFromNib() {
super.awakeFromNib()
layer.masksToBounds = true
layer.cornerRadius = 20
layer.maskedCorners = [.layerMinXMinYCorner,.layerMaxXMinYCorner]
}
}
Subclassing UITabBarController then overried viewWillLayoutSubviews()
and add this code .
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
self.tabBar.layer.masksToBounds = true
self.tabBar.layer.cornerRadius = 12 // whatever you want
self.tabBar.layer.maskedCorners = [.layerMinXMinYCorner,.layerMaxXMinYCorner] // only the top right and left corners
}
This will be the result

popOverView of dynamic size on clicking UitableView Cell

How to create a popover of dynamic size on clicking UitableView cell in swift?
Should i use any tooltip frameworks? or just use apples PopOverViewController functionality?
It works fine in iPad with the below code. but in iphone it appears as a full screen view
Below code works fine and is the solution i got UIPopoverPresentationController on iPhone doesn't produce popover
by #tsik
class CommonViewController: UIViewController, UIPopoverPresentationControllerDelegate{
func adaptivePresentationStyle(
for controller: UIPresentationController,
traitCollection: UITraitCollection)
-> UIModalPresentationStyle {
return .none
}
func showPopover(){
let storyboard = UIStoryboard(name: "Pickers", bundle: nil)
let myViewController = UIViewController()
myViewController.preferredContentSize = CGSize(width: 320, height: 200)
myViewController.modalPresentationStyle = .popover
let popOver = myViewController.popoverPresentationController
popOver?.delegate = self
self.present(myViewController, animated: true, completion: nil)
popOver?.permittedArrowDirections = .init(rawValue: 0)
popOver?.sourceView = self.view
let rect = CGRect(
origin: CGPoint(x: self.view.frame.width/2, y: self.view.frame.height/2),
size: CGSize(width: 1, height: 1)
)
popOver?.sourceRect = rect
}
could you please check this code this is working fine in iphones in my case.
let popoverContent = self.storyboard!.instantiateViewController(withIdentifier: "PopOverViewController")
let ktagForLabel = 100
let popOverWidth = UIScreen.main.bounds.width - 40
if let label = popoverContent.view.viewWithTag(ktagForLabel) as? UILabel {
let descriptionText = self.subcategoryDetailViewModel.displayServiceDescriptionForPopOver(forIndex: sender.tag/10)
label.text = descriptionText
var estimatedTextHeight = descriptionText.heightWithConstrainedWidth(width: popOverWidth, font: UIFont.systemFont(ofSize: 15)) + 16
let nav = UINavigationController(rootViewController: popoverContent)
nav.isNavigationBarHidden = true
nav.modalPresentationStyle = UIModalPresentationStyle.popover
let popover = nav.popoverPresentationController!
estimatedTextHeight = estimatedTextHeight > 150 ? 150: estimatedTextHeight
popoverContent.preferredContentSize = CGSize(width: popOverWidth, height: estimatedTextHeight)
popover.delegate = self
popover.permittedArrowDirections = .up
popover.sourceView = sender
popover.sourceRect = sender.bounds
self.present(nav, animated: true, completion: nil)
}

How to dismiss presentation controller with a custom animation

I'm using Custom Segue class to navigate between controllers.
class CustomSegue: UIStoryboardSegue {
override func perform() {
let firstVCView = self.source.view as UIView!
let secondVCView = self.destination.view as UIView!
let screenWidth = UIScreen.main.bounds.size.width
let screenHeight = UIScreen.main.bounds.size.height
secondVCView?.frame = CGRect(x: 0.0, y: screenHeight, width: screenWidth, height: screenHeight)
let window = UIApplication.shared.keyWindow
window?.insertSubview(secondVCView!, aboveSubview: firstVCView!)
UIView.animate(withDuration: 0.4, animations: { () -> Void in
firstVCView?.frame = (firstVCView?.frame.offsetBy(dx: 0.0, dy: -screenHeight))!
secondVCView?.frame = (secondVCView?.frame.offsetBy(dx: 0.0, dy: -screenHeight))!
}) { (Finished) -> Void in
self.source.present(self.destination as UIViewController,
animated: false,
completion: nil)
}
}
}
my question is how to dismiss with the opposite animation,
in dismiss method, I don't have the source/destination view to take the width and height.Thanks!
You probably found out already, but for other people landing on this topic, the solution is given in this post, namely doing the animation in the ViewController and then dismiss without animation.
Swift 4 code:
#IBAction func BackAction(_ sender: Any) {
let transition: CATransition = CATransition()
transition.duration = 0.5
transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
transition.type = CATransitionType.reveal
transition.subtype = CATransitionSubtype.fromLeft
self.view.window!.layer.add(transition, forKey: nil)
self.dismiss(animated: false, completion: nil)
}

Swift, Add a navigation controller in custom activity indicator

My Custom Activity indicator is not overlapping Navigation controller.
Below is my code
func showActivityIndicator(uiView: UIView) {
container.frame = uiView.frame
container.center = uiView.center
container.backgroundColor = UIColorFromHex(0xffffff, alpha: 0.1)
var loadingView: UIView = UIView()
loadingView.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
loadingView.center = uiView.center
loadingView.backgroundColor = UIColorFromHex(0x444444, alpha: 0.5)
loadingView.clipsToBounds = true
loadingView.layer.cornerRadius = 10
var imageData = NSData(contentsOfURL: NSBundle.mainBundle()
.URLForResource("synch-loader", withExtension: "gif")!)
let try = UIImage.animatedImageWithData(imageData!)
var imageView = UIImageView(image: try)
imageView.center = uiView.center
imageView.frame = CGRect(x: uiView.frame.width/4, y: uiView.frame.height/2, width: 500, height: 15)
loadingView.addSubview(imageView)
container.addSubview(loadingView)
uiView.addSubview(container)
actInd.startAnimating()
}
func navigationHandling()
{
if self.navigationController != nil {
self.navigationController?.navigationBar.tintColor = utility.uicolorFromHex(0x70B420)
self.navigationController?.navigationBar.barTintColor = utility.uicolorFromHex(0x70B420)
self.navigationController?.navigationBarHidden = false
self.navigationItem.hidesBackButton = true
}
sortingBtn = UIBarButtonItem(image: sortingImg, style: UIBarButtonItemStyle.Done, target: self, action: Selector("sortingPressed:"))
menuBtn = UIBarButtonItem(image: menuImg, style: UIBarButtonItemStyle.Plain, target: self, action : nil)
sortingBtn.tintColor = UIColor.whiteColor()
menuBtn.tintColor = UIColor.whiteColor()
var buttons : NSArray = [menuBtn,sortingBtn]
self.navigationItem.rightBarButtonItems = buttons as [AnyObject]
self.navigationItem.setRightBarButtonItems([menuBtn,sortingBtn], animated: true)
networkLabel.hidden = true
}
I just want to overlap the view on navigation controller so that it don't looks ugly.
I appreciate help!
let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate
let window = appDelegate?.window
window.addSubview("yourActivityIndicator")
Here add the activity indicator to the window, or pass the window in as the view.
let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate
let window = appDelegate?.window
showActivityIndicator(window)
The uiView you're passing as parameter to this method
func showActivityIndicator(uiView: UIView)
is your ViewController's view or your UINavigationController's view?
Because if it's your UIViewController's view your custom loading will take it's size and origin, that is under your NavigationBar