Once I switched to xCode 9, my initialization of a UITextView stopped working:
#IBOutlet weak var txtPirepText: UITextView!
override func viewDidLoad()
{
if UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad
{
self.txtPirepText = UITextView(frame: CGRect(x: 60, y: 380, width: 900, height: 280))
print("IS THIS VALUE NIL? ",self.txtPirepText)
self.txtPirepText.text = ""
self.txtPirepText.font = UIFont(name: "Arial-BoldMT", size: 17)
self.txtPirepText.textColor = UIColor.black
}
}
The print shows that the value is nil and the application crashes on trying to set a text.
Does such initialization not work any more? Thank you!
Related
I'm trying to create a growing TextEditor as input for a chat view.
The goal is to have a box which expands until 6 lines are reached for example. After that it should be scrollable.
I already managed to do this with strings, which contain line breaks \n.
TextEditor(text: $composedMessage)
.onChange(of: self.composedMessage, perform: { value in
withAnimation(.easeInOut(duration: 0.1), {
if (value.numberOfLines() < 6) {
height = startHeight + CGFloat((value.numberOfLines() * 20))
}
if value.numberOfLines() == 0 || value.isEmpty {
height = 50
}
})
})
I created a string extension which returns the number of line breaks by calling string.numberOfLines() var startHeight: CGFloat = 50
The problem: If I paste a text which contains a really long text, it's not expanding when this string has no line breaks. The text get's broken in the TextEditor.
How can I count the number of breaks the TextEditor makes and put a new line character at that position?
Here's a solution adapted from question and answer,
struct ChatView: View {
#State var text: String = ""
// initial height
#State var height: CGFloat = 30
var body: some View {
ZStack(alignment: .topLeading) {
Text("Placeholder")
.foregroundColor(.appLightGray)
.font(Font.custom(CustomFont.sofiaProMedium, size: 13.5))
.padding(.horizontal, 4)
.padding(.vertical, 9)
.opacity(text.isEmpty ? 1 : 0)
TextEditor(text: $text)
.foregroundColor(.appBlack)
.font(Font.custom(CustomFont.sofiaProMedium, size: 14))
.frame(height: height)
.opacity(text.isEmpty ? 0.25 : 1)
.onChange(of: self.text, perform: { value in
withAnimation(.easeInOut(duration: 0.1), {
if (value.numberOfLines() < 6) {
// new height
height = 120
}
if value.numberOfLines() == 0 || value.isEmpty {
// initial height
height = 30
}
})
})
}
.padding(4)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color.appLightGray, lineWidth: 0.5)
)
}
}
And the extension,
extension String {
func numberOfLines() -> Int {
return self.numberOfOccurrencesOf(string: "\n") + 1
}
func numberOfOccurrencesOf(string: String) -> Int {
return self.components(separatedBy:string).count - 1
}
}
I found a solution!
For everyone else trying to solve this:
I added a Text with the same width of the input field and then used a GeometryReader to calculate the height of the Text which automatically wraps. Then if you divide the height by the font size you get the number of lines.
You can make the text field hidden (tested in iOS 14 and iOS 15 beta 3)
If you're looking for an iOS 15 solution, I spent a while and figured it out. I didn't want to have to resort to UIKit or ZStacks with overlays or duplicative content as a "hack". I wanted it to be pure SwiftUI.
I ended up creating a separate struct that I could reuse anywhere I needed it, as well as add additional parameters in my various views.
Here's the struct:
struct FieldMultiEntryTextDynamic: View {
var text: Binding<String>
var body: some View {
TextEditor(text: text)
.padding(.vertical, -8)
.padding(.horizontal, -4)
.frame(minHeight: 0, maxHeight: 300)
.font(.custom("HelveticaNeue", size: 17, relativeTo: .headline))
.foregroundColor(.primary)
.dynamicTypeSize(.medium ... .xxLarge)
.fixedSize(horizontal: false, vertical: true)
} // End Var Body
} // End Struct
The cool thing about this is that you can have placeholder text via an if statement and it supports dynamic type sizes.
You can implement it as follows:
struct MyView: View {
#FocusState private var isFocused: Bool
#State private var myName: String = ""
var body: some View {
HStack(alignment: .top) {
Text("Name:")
ZStack(alignment: .trailing) {
if myName.isEmpty && !isFocused {
Text("Type Your Name")
.font(.custom("HelveticaNeue", size: 17, relativeTo: .headline))
.foregroundColor(.secondary)
}
HStack {
VStack(alignment: .trailing, spacing: 5) {
FieldMultiEntryTextDynamic(text: $myName)
.multilineTextAlignment(.trailing)
.keyboardType(.alphabet)
.focused($isFocused)
}
}
}
}
.padding()
.background(.blue)
}
}
Hope it helps!
I am using react-native-navigation and trying to add a native view on the top of everything. I initialized the Swift class in AppDelegate and call swift func:
func showUp() {
let window = UIApplication.shared.keyWindow!
let rect = UIView(frame: CGRect(x: 50, y: 50, width: 100, height: 50))
rect.backgroundColor = UIColor.white
window.addSubview(rect) }
The View seemed to be appeared while loading app and then disappears after app is
loaded.
Thanks in advance)
I'm having trouble drawing polylines, and I think I've deduced it to being an issue with iOS 11 beta 4. It was working yesterday with the same code, and now I've updated to beta 4 and it doesn't draw polylines.
Just confirmed this by trying it in Xcode 8 on iOS 10.3 simulator, and in Xcode 9b4 on the iOS 11b4 simulator.
Code:
import MapKit
class ViewController: UIViewController, MKMapViewDelegate {
let mapView = MKMapView()
override func viewDidLoad() {
super.viewDidLoad()
mapView.frame = CGRect(x: 10, y: 10, width: 300, height: 300)
mapView.delegate = self
mapView.region = MKCoordinateRegionMake(CLLocationCoordinate2D(latitude: 51.482736, longitude: -0.015253), MKCoordinateSpanMake(0.005, 0.005))
mapView.delegate = self
let coordinate1 = CLLocationCoordinate2D(latitude: 51.482736, longitude: -0.015253)
let coordinate2 = CLLocationCoordinate2D(latitude: 51.482736, longitude: -0.016253)
let polyline = MKPolyline(coordinates: [coordinate1, coordinate2], count: 2)
mapView.add(polyline, level: .aboveLabels)
view.addSubview(mapView)
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = UIColor.red
renderer.lineWidth = 4.0
return renderer
}
}
iOS 10:
iOS 11:
Annotations are added to the map without issue.
Fixed in beta 5. We just had to wait.
I recently switched from using PaintCode 2 to PaintCode 3, I am using it together with xCode/Swift.
I noticed however, that all my image generating functions not behave differently. They seam to standard addopt cap insets.
As an example below you can find one canvas "ViewMissingImage", and how its configured in PaintCode (2 or 3 its identical).
Code generated via PaintCode 2
public class func imageOfViewMissingImage(frame frame: CGRect = CGRect(x: 6, y: 5, width: 109, height: 109)) -> UIImage {
UIGraphicsBeginImageContextWithOptions(frame.size, false, 0)
PaintCode.drawViewMissingImage(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height))
let imageOfViewMissingImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return imageOfViewMissingImage
}
Code generated via PaintCode 3
public dynamic class func imageOfViewMissingImage(imageSize imageSize: CGSize = CGSize(width: 109, height: 109)) -> UIImage {
UIGraphicsBeginImageContextWithOptions(imageSize, false, 0)
PaintCode.drawViewMissingImage(frame: CGRect(x: 0, y: 0, width: imageSize.width, height: imageSize.height))
let imageOfViewMissingImage = UIGraphicsGetImageFromCurrentImageContext()!.resizableImageWithCapInsets(UIEdgeInsetsZero, resizingMode: .Tile)
UIGraphicsEndImageContext()
return imageOfViewMissingImage
}
I think that the PaintCode 2 never used the capp insets, maybe it was a bug?
I do not want these cap insets, how can I get rid of them?
The solution is straightforward:
Put the Cap Inset on "Stretch" instead of tile in PaintCode UI!
Hello friends,
I am developing a functionality to display index number on map pin and set image on mapview of iPhone so please tell me any link or any idea to develop this functionality.
Thanks in advance.
What is an index number in the context? Is it just a digit that your code is displaying? If so your question is how to display text on a map. Use a map overlay. Same for images. Search for MKMapOverlay and go from there.
I have use this method for index number in annotation view.
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
guard !(annotation is MKUserLocation) else {
return nil
}
// Better to make this class property
let annotationIdentifier = "AnnotationIdentifier"
var annotationView = MKAnnotationView()
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier)
annotationView.frame = CGRect(x: annotationView.frame.origin.x, y: annotationView.frame.origin.y, width: 80, height: 200)
annotationView.annotation = annotation
annotationView.tag = index
index += 1
let imageViewPin = UIImageView(frame: CGRect(x: 0, y: 0, width: 30, height: 40))
imageViewPin.center = CGPoint(x: annotationView.center.x, y: annotationView.center.y - 11)
imageViewPin.image = UIImage(named: "green_pin")
annotationView.addSubview(imageViewPin)
return annotationView
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
debugPrint(view.tag)
}