swift: after adding navigationController to viewController, tableView height is not fitting screen - swift

after adding this codes to appDelegate inside didFinishLaunchingWithOptions function:
self.window = UIWindow(frame: UIScreen.main.bounds)
let mainView = PageViewController(coder: NSCoder())
let nav1 = UINavigationController(rootViewController: mainView!)
nav1.navigationBar.isTranslucent = false
self.window!.rootViewController = nav1
self.window?.makeKeyAndVisible()
tableView height is not looking good, some part of tableView(cells) not fitting screen
my codes for implementing tableView:
let myTableView = UITableView(frame: CGRect(x: 0, y: 40, width: screenSize.width, height: screenSize.height-40))
myTableView.bounces = false
myTableView.tableFooterView = UIView()
myTableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellID")
myTableView.register(MyTableViewCell.self, forCellReuseIdentifier: "cellID2")
myTableView.dataSource = self
myTableView.delegate = self
for show all part of tableView in screen i have to change the first line above code to this:
let myTableView = UITableView(frame: CGRect(x: 0, y: 40, width: screenSize.width, height: screenSize.height-90))
why this is happening and what should i do to solve this problem thanks

Try something like this but don't forget to add myTableView as a subview before you set anchors:
myTableView.translatesAutoresizingMaskIntoConstraints = false
myTableView.leftAnchor.constraint(equalTo: myTableView.superview!.leftAnchor).isActive = true
myTableView.rightAnchor.constraint(equalTo: myTableView.superview!.rightAnchor).isActive = true
myTableView.topAnchor.constraint(equalTo: myTableView.superview!.topAnchor).isActive = true
myTableView.bottomAnchor.constraint(equalTo: myTableView.superview!.bottomAnchor).isActive = true

Related

Issue reusing the same UI Image code across multiple view controllers | Swift 5

I have the following function I use to customize the navigation bar across almost all the apps view controllers and table view controllers - instead of replicating the code numerous times I am looking for way to easily call the function on those view controllers needing it.
I have tried wrapping in extension UIViewController { } but run into a selector issue saying the following:
Argument of '#selector' cannot refer to local function
'Tapped(tapGestureRecognizer:)'
Code:
func navBar(){
// Profile Image
let containView = UIView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
imageView.image = UIImage(url: URL(string: "test.com"))
imageView.contentMode = UIView.ContentMode.scaleAspectFit
imageView.layer.cornerRadius = 20
imageView.layer.masksToBounds = true
containView.addSubview(imageView)
let rightBarButton = UIBarButtonItem(customView: containView)
self.navigationItem.rightBarButtonItem = rightBarButton
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
imageView.isUserInteractionEnabled = true
imageView.addGestureRecognizer(tapGestureRecognizer)
}
#objc func imageTapped(tapGestureRecognizer: UITapGestureRecognizer) {
print("Profile Tapped")
}
How can this UIImage be seen in the navigation bar across various view controller without needing to rewrite the same code across all.
Lot a way to do it. I'll usually istance and personalize an UIViewController and use it around the whole app.
class baseController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//call your navBar here
navbar()
}
func navBar(){
// Profile Image
let containView = UIView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
imageView.image = UIImage(url: URL(string: "test.com"))
imageView.contentMode = UIView.ContentMode.scaleAspectFit
imageView.layer.cornerRadius = 20
imageView.layer.masksToBounds = true
containView.addSubview(imageView)
let rightBarButton = UIBarButtonItem(customView: containView)
self.navigationItem.rightBarButtonItem = rightBarButton
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
imageView.isUserInteractionEnabled = true
imageView.addGestureRecognizer(tapGestureRecognizer)
}
}
Now instance this class whenever you want and your controller will get your navBar() every time with this
class mineController:baseController {
//your code here...
}

Swift: SegmentedControl in NavBar with Small TitleView

I am attempting to include a segmentedControl on my navBar that looks like this:
The idea here is that the text "fetching..." is a small titleView. However, my current implementation would result in the text "fetching..." on the lower side like so:
I implement large titles so that I can get two "rows" on the navBar, else the word "fetching..." will be hidden behind the segmentedControl.
Code:
let segmentedControl: UISegmentedControl = {
let items = ["Now","In 15 mins", "In 1 hour"]
let sc = UISegmentedControl(items: items)
sc.selectedSegmentIndex = 0
return sc
}()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.backBarButtonItem?.title = "Back"
navigationItem.largeTitleDisplayMode = .automatic
navigationItem.titleView = segmentedControl
}
Does anyone have any advice?
You can create a customView that holds all the views you want to show in the navigation bar and set that view as titleView like below,
let segmentedControl: UISegmentedControl = {
let items = ["Now","In 15 mins", "In 1 hour"]
let sc = UISegmentedControl(items: items)
sc.selectedSegmentIndex = 0
return sc
}()
let fetchingLabel: UILabel = {
let label = UILabel(frame: .zero)
label.text = "Fetching..."
return label
}()
In viewDidLoad
let customView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 250))
customView.addSubview(segmentedControl)
customView.addSubview(fetchingLabel)
fetchingLabel.frame = CGRect(x: 150, y: 0, width: self.view.frame.width, height: 60)
segmentedControl.frame = CGRect(x: 60, y: 50, width: self.view.frame.width * 0.75, height: 30)
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.largeTitleDisplayMode = .automatic
navigationItem.titleView = customView
This should give you below result. You can play with the values to do what you want.

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)
}

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

window can't addsubview with swift

In function Appdelegate - didFinishLaunchingWithOptions implement :
var testView : UIView = UIView(frame: CGRectMake(100, 100, 100, 100))
testView.backgroundColor = UIColor.blueColor()
self.window?.addSubview(testView)
self.window?.bringSubviewToFront(testView)
self.window?.makeKeyAndVisible()
But not show testView.
All you need to do is give frame to your window.
and your code will be:
window = UIWindow(frame: UIScreen.mainScreen().bounds)
var testView : UIView = UIView(frame: CGRectMake(0 , 0, 100, 100))
testView.backgroundColor = UIColor.blueColor()
self.window?.addSubview(testView)
self.window?.bringSubviewToFront(testView)
self.window?.makeKeyAndVisible()