how to add textfield as a custom view in leftBarButtonItems, here textfield need to be capable to typing - swift3

how to add a new view that view having textfield and buttons in it and how this view can be added in leftbarbuttonitmes, and textfield need to be capable to typing.
Right now I have added this view to leftbarbuttonitems successfully but my textfield is not capable to type. Is there any way by which we can type if we add in leftbarbuttonitems.

Here it is: Just paste below code in your viewDidLoad method.
let viewLeftButton: UIView = UIView(frame: CGRect(x: 0, y: 0, width: 160.0, height: 32.0))
let textField: UITextField = UITextField(frame: CGRect(x: 0, y: 0, width: 100.0, height: viewLeftButton.frame.size.height))
textField.borderStyle = .roundedRect
textField.font = UIFont.systemFont(ofSize: 14.0)
textField.placeholder = "Type here..."
let button: UIButton = UIButton(frame: CGRect(x: textField.frame.size.width + 8, y: 0, width: 44.0, height: viewLeftButton.frame.size.height))
button.setTitle("Click", for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 14.0)
button.setTitleColor(.blue, for: .normal)
viewLeftButton.addSubview(textField)
viewLeftButton.addSubview(button)
self.navigationItem.hidesBackButton = true
let leftBarButton = UIBarButtonItem(customView: viewLeftButton)
self.navigationItem.leftBarButtonItem = leftBarButton

Related

Gradient not redrawing properly

I am attempting to have a CGRect that has a dynamic gradient. When I use the view models gradient I am able to observe the gradient changing. However the view does not change as expected.
If I use hardcoded gradients in the view which toggle between red and blue I see that the view is redrawing with the updated gradient.
What am I missing?
View Model:
#Published var forceRedraw: Bool = false
#Published var annGradient: Gradient = Gradient(colors: [.red]) {
didSet {
print("ViewModel", annGradient.stops.first!, annGradient.stops.last!)
forceRedraw.toggle()
}
}
View:
struct SchematicView: View {
#EnvironmentObject var vM: AppViewModel
#State var refresh: Bool = false
var body: some View {
VStack(alignment: .center) {
Spacer()
ScrollView {
if refresh {
Canvas { context, size in
let w = size.width
let h = size.height
let grad = vM.annGradient
print("View1", grad.stops.first!, grad.stops.last!)
let annPath = CGRect(x: w/2, y: 0, width: 100, height: h)
context.fill(Path(annPath), with: .linearGradient(grad, startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0, y: h)))
}.frame(width: 300, height: 500)
} else {
Canvas { context, size in
let w = size.width
let h = size.height
let grad = vM.annGradient
print("View2", grad.stops.first!, grad.stops.last!)
let annPath = CGRect(x: w/2, y: 0, width: 100, height: h)
context.fill(Path(annPath), with: .linearGradient(grad, startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0, y: h)))
}.frame(width: 300, height: 500)
}
}
.syncBool($vM.forceRedraw, with: $refresh)
.onAppear(perform: {
refresh = vM.forceRedraw
})

How to identify variables with the same identifier in different subViews

First post and I'll be honest, I'm pretty bad at coding. I'm working with Swift 3 for a school project and I have a question.
I'm creating multiple subviews through a for in loop through an array...
...and each created subview contains one programmatically created label, each with a different word, and a programmatically created UI Tap Gesture attached to each view...
Import UIKit
class ViewController: UIViewController, UIGestureRecongizerDelegate
{
var array = ["Each","One","Has","Its","Own","Name"]
var label = UILabel()
var DynamicView = UIView()
var count = 0
override func viewDidLoad() {
super.viewDidLoad()
createSubView()
//end SuperView
}
func createSubview()
{
for thing in array {
var string = array[count]
count = count + 1
DynamicView = UIView(frame: CGRect(x: 0, y: 0, width: 120, height: 160))
DynamicView.center = CGPoint(x: xV,y: yV)
DynamicView.backgroundColor = UIColor.gray
self.view.addSubview(DynamicView)
label = UILabel(frame: CGRect(x: 25, y: 25, width: 100, height: 21))
label.center = CGPoint(x: 60, y: 13)
label.textAlignment = .center
label.font = UIFont(name: "Arial", size: 13)
label.text = "\(string)"
self.DynamicView.addSubview(label)
let tapGesture = UITapGestureRecognizer(target: self, action:
#selector(ViewController.tapped(recignizer:)))
DynamicView.isUserInteractionEnabled = true
DynamicView.addGestureRecognizer(tapGesture)
}
}
func tapped (recignizer:UITapGestureRecognizer){
print("\(label.text!)")
}
}
... (I'm excluding the code that separates all the views from being stacked on top of each other, so please assume that these views are spaced out, and this list of views is in a scroll view in my actual code, just not cramming that spaghetti code in here)...
...The result of the code is a layout of subViews, each with its own label that is a different word, and a tap gesture for each subView which triggers a function...
...What I want is a way to tap on each subview and find what the text in the label is. As of right now, when you tap on a view, you get what the label.text was in the last View made, so the result of print("label.text!") --> 'Name' , which makes some sense.
Is there any possible way to find the specific labels text even though they are all called "Label"?
I'm not looking to do a collection view or anything of the sort, I need something of this sort of coding to get what I need done.
Thank you to whoever helped this foolish swift student, sorry that my Swift lingo is hot garbage like my code.
Your problem is you are initializing the same DynamicView and label inside the for loop so it will overwrite and it will have last value from the array. To solved the problem you need to create separate UIView and separate UILabel in for loop. Also you need to set userInteraction of label to true because by default its false.
for thing in array {
let dynamicView = UIView(frame: CGRect(x: 0, y: 0, width: 120, height: 160))
dynamicView.center = CGPoint(x: xV,y: yV)
dynamicView.backgroundColor = UIColor.gray
self.view.addSubview(dynamicView)
let label = UILabel(frame: CGRect(x: 25, y: 25, width: 100, height: 21))
label.center = CGPoint(x: 60, y: 13)
label.textAlignment = .center
label.font = UIFont(name: "Arial", size: 13)
label.text = thing
self.dynamicView.addSubview(label)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.tapped(recignizer:)))
label.isUserInteractionEnabled = true
label.addGestureRecognizer(tapGesture)
}
Now your all view’s origin is CGPoint.zero so only last view label will visible and when you tap on label to get text of its you can get this way.
func tapped(recignizer:UITapGestureRecognizer){
if let tappedLabel = recignizer.view as? UILabel {
print("\(tappedLabel.text)”)
}
}

TableView Expand/Collapse with Swift 3

I did collapse/expand table cell in swift 3. But, I would like to add some padding bottom to the title header. In my screenshot, there is no padding between Title 1 and Title 2.
Another problem is that how can I move arrow image to the right?
Here is my code.
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView.init(frame: CGRect(x: 0, y: 0, width: 300, height: 28))
var imageView = UIImageView()
if (expandSections.contains(section)) {
imageView = UIImageView.init(frame: CGRect(x: 7, y: 5, width: 25, height: 25))
imageView.image = UIImage(named: "down_image")
} else {
imageView = UIImageView.init(frame: CGRect(x: 7, y: 5, width: 25, height: 25))
imageView.image = UIImage(named: "up_image")
}
let headerTitle = UILabel.init(frame: CGRect(x: 38, y: 4, width: 250, height: 28))
headerTitle.text = sectionData[section]
headerTitle.textColor = UIColor.white
let tappedSection = UIButton.init(frame: CGRect(x: 0, y: 0, width: headerView.frame.size.width, height: headerView.frame.size.height))
tappedSection.addTarget(self, action: #selector(sectionTapped), for: .touchUpInside)
tappedSection.tag = section
headerView.addSubview(imageView)
headerView.addSubview(headerTitle)
headerView.addSubview(tappedSection)
headerView.backgroundColor = UIColor.lightGray
return headerView
}
Try this, In here I added another view inside of headerView. Then only u can add padding in headerView.
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView.init(frame: CGRect(x: 0, y: 0, width: 300, height: 28))
let internalView = UIView.init(frame: CGRect(x: 0, y: 0, width: 300, height: 25))
var imageView = UIImageView()
if (expandSections.contains(section)) {
imageView = UIImageView.init(frame: CGRect(x: internalView.frame.size.width - 10 , y: 5, width: 25, height: 25))
imageView.image = UIImage(named: "down_image")
} else {
imageView = UIImageView.init(frame: CGRect(x: internalView.frame.size.width - 10 , y: 5, width: 25, height: 25))
imageView.image = UIImage(named: "up_image")
}
let headerTitle = UILabel.init(frame: CGRect(x: 38, y: 4, width: 250, height: 28))
headerTitle.text = sectionData[section]
headerTitle.textColor = UIColor.white
let tappedSection = UIButton.init(frame: CGRect(x: 0, y: 0, width: headerView.frame.size.width, height: headerView.frame.size.height))
tappedSection.addTarget(self, action: #selector(sectionTapped), for: .touchUpInside)
tappedSection.tag = section
internalView.addSubview(imageView)
internalView.addSubview(headerTitle)
internalView.addSubview(tappedSection)
headerView.addSubview(internalView)
headerView.backgroundColor = UIColor.lightGray
return headerView
}

How to make a CGRect animate

How can I create an animation like this one?
override func draw(_ rect: CGRect)
{
let xPointRect = viewWithTag(1)?.alignmentRect(forFrame: rect).midX
let yPointRect = viewWithTag(1)?.alignmentRect(forFrame: rect).midY
let widthSize = self.viewWithTag(1)?.frame.size.width
let heightSize = self.viewWithTag(1)?.frame.size.height
let sizeRect = CGSize(width: widthSize! * 0.8, height: heightSize! * 0.4)
let rectPlacementX = CGFloat(sizeRect.width/2)
let rectPlacementY = CGFloat(sizeRect.height/2)
let context2 = UIGraphicsGetCurrentContext()
context2?.setLineWidth(2.0)
context2?.setStrokeColor(UIColor.red.cgColor)
context2?.move(to: CGPoint(x: (xPointRect! - rectPlacementX), y: (yPointRect! - rectPlacementY)))
context2?.addLine(to: CGPoint(x: (xPointRect! + rectPlacementX), y: (yPointRect! + rectPlacementY)))
context2?.setLineDash(phase: 3, lengths: dashArray)
context2?.strokePath()
context2.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
UIView.animate(withDuration: 1.0,
delay: 0,
usingSpringWithDamping: 0.15,
initialSpringVelocity: 6.0,
options: .allowUserInteraction,
animations: { context2.transform = CGAffineTransform.identity },
completion: nil)
}
My current code is not working because context2 doesn't contain a member .transfer since it is a CGRect.
How can I make this line animate? Any idea?
A CGRect is not visible, so I do not see why you want to animate it.
I assume what you want to animate the frame of a UIView.
You can change many properties of a UIView in an animation block. Also it's frame:
let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
someParentView.addSubview(view)
UIView.animate(withDuration: 2.5) {
someUIView.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
}

add action to programmatically created uibuttons

I have written a class file to create a topBar for my app, I also add in buttons to the top bar after adding target to the buttons added, the same is not triggered
the line menuButton.addTarget(self, action: #selector(showMenu), for: .touchUpInside) does not trigger the function showMenu
I create a TN object(from class TopNav) in the main view file and add it to the view, but the menu button does not trigger the tap
import Foundation
import UIKit
class TopNav{
var topView: UIView = UIView()
var menuButton: UIButton = UIButton()
#objc func showMenu(sender: UIButton!) {
print("show Menu")
}
func position(){
let bounds = UIScreen.main.bounds
let width = bounds.size.width
topView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: width, height: 60.0))
topView.backgroundColor = UIColor.init(colorLiteralRed: 66/255, green: 74/255, blue: 87/255, alpha: 1.0)
menuButton = UIButton(frame: CGRect(x: (width-40), y: 20.0, width: 30.0, height: 30.0))
menuButton.setBackgroundImage( UIImage(named:"menu"), for: .normal)
menuButton.setTitle("", for: UIControlState.normal)
menuButton.addTarget(self, action: #selector(showMenu), for: .touchUpInside)
topView.addSubview(menuButton)
}
}
You may try this.
class TopNav {
func position() {
...
menuButton.addTarget(self, action: #selector(TopNav.showMenu), for: .touchUpInside)
...
}
func showMenu() {
//your code
}
}