expanding a text view when user clicks on "more..." - xcode

There are applications with a text field that shows a given amount of lines and when the user clicks more it expands and shows the rest,
I'm familiar with the code to expand my UITextView but not sure how to add the "more..." and then "less...",
option to
Fine tuning the question: I'm not looking to add a button but having the default IOS behavior when the text is larger than the size of a control it will either place ... at the end or in the middle for example: this is ... or thi...long

you can take one button and add that UIButton to view below the UITextView and when you click on that button change the button positions and title related to the UITextView.

You can implement that using the Method (sizeWithFont:constrainedToSize:lineBreakMode:)
Firstly take out the size of the text you need show into the TextField like this
NSString *textToBeShown = #"jhfsdg djsgf jdsfsdf dsf";
CGSize textSize = [textToBeShown sizeWithFont:[UIFont fontWithName:#"Arial-BoldMT" size:11]]
constrainedToSize:CGSizeMake(constrainedWidth,constrainedHeight)
lineBreakMode:NSLineBreakByWordWrapping];
Suppose you want your textview height to be 100.0 initially before pressing "ShowMore" button then you can check the textSize.height in comparison to the 100.0 , if the textHeight is less then 100.0 then assign the TextView's Heigth as textSize.height else assign it 100.0 pixel .
Now when the show more button is clicked assign the textSize.height as the height of the UITextView used to show the text .
NSString *textToBeShown = #"jhfsdg djsgf jdsfsdf dsf";
CGSize textSize = [textToBeShown sizeWithFont:[UIFont fontWithName:#"Arial-BoldMT" size:11]]
constrainedToSize:CGSizeMake(constrainedWidth,constrainedHeight)
lineBreakMode:NSLineBreakByWordWrapping];
textView.frame=CGRectMale(textView.frame.origin.x,
textView.frame.origin.y,
textSize.width,
textSize.height);

Related

How to move a view based on validation uikit swift

I have a validation inside of my app and a textfield both are located on different areas of the same screen.
Textfield is on y = 200
Validation Button is on y = 800
Whenever I am at the point of the validating of y = 800 and my textfield is empty I need to automatically scroll on the background to y which is 200 from y = 800.
In short
if textfield is empty I need to go to this specific place (y=200) which is located in the beginning of the app.
I am not sure how to do it in uikit.
If you are using UIScrollView, you can call scrollRectToVisible and pass the textField's frame as parameter to this function.
scrollView.scrollRectToVisible(textField.frame, animated: true)

SwiftUI UI Test How To Display Dynamic Buttons Text Values in an app.scrollViews?

How To Display Dynamic Buttons Text Values in an app.scrollViews?
I would like to able to tap the button inside first row in the scrollViews, but not sure what the index of the button is. I tried the 1, 2 and 3 with no luck.
let scrollViewsQuery = app/*#START_MENU_TOKEN#*/.scrollViews/*[[".otherElements[\"Tabbar\"].scrollViews",".scrollViews"],[[[-1,1],[-1,0]]],[0]]#END_MENU_TOKEN#*/
let elementsQuery = scrollViewsQuery.otherElements
elementsQuery.buttons.element(boundBy: 0).tap() //
print("----------------------------------------------")
var i = 0
for element in elementsQuery.buttons.allElementsBoundByIndex{
i += 1
print(i)
print(element) //How To Display the Button Text here?
// print( elementsQuery.buttons.element(boundBy: i))
}
Assuming you only have one scrollView present, the code to tap the first button in it would be the following:
let myScrollView = app.scrollViews.firstMatch
let myScrollViewsButtons = myScrollView.buttons
let myScrollViewsFirstButton = myScrollViewButtons.firstMatch
myScrollViewsFirstButton.tap()
A button in this context is an XCUIElement, not something that is particularly printable. Buttons do have label attributes that are generally the text displayed on them...

NSAppearance is not updating when toggling dark mode

I have a macOS app that runs only in the macOS status bar. I changed the "Application is agent (UIElement)" property in the Info.plist to "YES":
<key>LSUIElement</key>
<true/>
I have a timer that prints out the appearance's name every 5 seconds like this:
Timer.scheduledTimer(withTimeInterval: 5, repeats: true) { _ in
let appearance = NSAppearance.currentDrawing()
print(appearance.name)
}
Problem
The name doesn't actually change when I toggle dark/light mode in system settings. It always prints the name of the appearance that was set when the application launched.
Is there a way to listen to system appearance changes?
Goal
My end goal is actually to draw an NSAttributedString to an NSImage, and use that NSImage as the NSStatusItem button's image.
let image: NSImage = // generate image
statusItem.button?.image = image
For the text in the attributed string I use UIColor.labelColor that is supposed to be based on the system appearance. However it seems to not respect the system appearance change.
When I start the application in Dark Mode and then switch to Light Mode:
When I start the application in Light Mode and then switch to Dark Mode:
Side note
The reason why I turn the NSAttributedString into an NSImage and don't use the NSAttributedString directly on the NSStatusItem button's attributedTitle is because it doesn't position correctly in the status bar.
The problem with drawing a NSAttributedString is, that NSAttributedString doesn't know how to render dynamic colors such as NSColor.labelColor. Thus, it doesn't react on appearance changes. You have to use a UI element.
Solution
I solved this problem by passing the NSAttributedString to a NSTextField and draw that into an NSImage. Works perfectly fine.
func updateStatusItemImage() {
// Use UI element: `NSTextField`
let attributedString: NSAttributedString = ...
let textField = NSTextField(labelWithAttributedString: attributedString)
textField.sizeToFit()
// Draw the `NSTextField` into an `NSImage`
let size = textField.frame.size
let image = NSImage(size: size)
image.lockFocus()
textField.draw(textField.bounds)
image.unlockFocus()
// Assign the drawn image to the button of the `NSStatusItem`
statusItem.button?.image = image
}
React on NSAppearance changes
In addition, since NSImage doesn't know about NSAppearance either I need to trigger a redraw on appearance changes by observing the effectiveAppearance property of the button of the NSStatusItem:
observation = statusItem.observe(\.button?.effectiveAppearance, options: []) { [weak self] _, _ in
// Redraw
self?.updateStatusItemImage()
}

Voice over do not work in NSMenu in status bar with custom view for NSMenuItem

I have added NSMenu in NSStatusBar. I have used custom views for first NSMenuItem with the setView: method to include progressIndicator. All other items are default.
Issue here is with VO (voice over for disabled people). When I enable VO from Setting -> Accessibility -> VoiceOver and press option+command+M+M it focus on menus in status bar. Now using left and right keys I navigate to my app and then press down key of open NSMenu.
I can got down and select my options but cannot change to other app (wifi, date) from here. When I remove this custom view item it works fine. I also observed same with one another app.
Do I need to set any properties for custom views.
Edit
I created sample app in swift.
let menu = NSMenu()
let menuitem1 = NSMenuItem()
let view1 = NSView(frame: NSRect(x: 0, y: 0, width: 100, height: 30))
menuitem1.view = view1
menu.addItem(menuitem1)
menu.addItem(NSMenuItem(title: "Print Quote", action: #selector(AppDelegate.printQuote(_:)), keyEquivalent: "P"))
menu.addItem(NSMenuItem.separator())
menu.addItem(NSMenuItem(title: "Quit Quotes", action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q"))
Even in this simple app I cannot get VO working properly.
Steps
VO (control+option) + M + M
VO + space to select our app options.
VO + down key to navigate inside.
Then try to go left or right in other apps. It do not switch to other app.
Edit 2
Observation is when I choose custom view first and try to switch to other app it works. But once I choose normal menuitem from custom view it falls in some issue. Only solution I find is either have all default menu items or all items with custom view.
For my NSMenuItems displayed in a table, I can add the accessibilityLabel on the newAutoLayoutView.
NSView *cellView = [NSView newAutoLayoutView];
cellView.accessibilityLabel = #"Voiceover Tab Name";

UITextField not scrolling horizontally

I am trying to make a small calculator app.
When a UIButton is pressed, the Button title is added to a UITextField.
kind of:
myuitextfield.text = [myuitextfield.text stringByAppendingString:[button currentTitle];
When I reach the end of my textfield, the text gets truncated. How can I disable this, so the textfield starts scrolling automatically and allows adding more characters?
I tried every possible option in Interface Builder, without any luck.
Isn't the UITextField supposed to scroll automatically? I can see this behavior when a native keyboard is used and text is entered.
I have chosen UITextField, as I need only 1 Line.
To illustrate the Problem:
When I enter text using my custom UIButtons text gets truncated
When I tap the UITextField and enter text using the keyboard I can enter unlimited text and the text is not truncated.
If you are facing this issue on iOS7, I've managed to fix it after been inspired by this post. In my case I had a field for entering an email address and after reaching the edge, the user could carry on typing but the text would be invisible (off-field).
First, add a callback to your UITextField so that you can track a text change to the field:
[self.field addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
Then evaluate the size in pixels of the entered string as it is typed and change the text alignment from left to right when reaching the edge of the field area:
- (void)textFieldDidChange:(NSNotification *)aNotif{
float maxNumPixelsOnScreen = 235; // Change this value to fit your case
CGSize maximumSize = CGSizeMake(maxNumPixelsOnScreen + 10, 1);
NSString *aString = self.field.text;
CGSize stringSize = [aString sizeWithFont:fieldFont
constrainedToSize:maximumSize
lineBreakMode:NSLineBreakByWordWrapping];
self.field.textAlignment = NSTextAlignmentLeft;
if (stringSize.width >= maxNumPixelsOnScreen)
self.field.textAlignment = NSTextAlignmentRight;
}
Note:
self.field is the offending UITextField
maximumSize: I'm adding 10 the the width to be slightly over the limit defined
fieldFont is the UIFont used to render the text field
Hope it helps!
you have to add UITextview and limit the number of lines to 2.Textfield doesnt work with two lines.Textview is same as textfields except the delegates and some properties differ.

Resources