I am making a To do list app and well I need to create a delete button so when the self (user) swipes the task to the left a red button will say delete.
So well I started to create the code imported from UITableViewDataSource and well the code I am trying to use is if(editingStyle) == UITableViewCellEditingStyle.Delete) and well when I put it into the code, the code throws back a error saying (!) Expected '{' after 'if' condition.
So is there anyway to get round this because I have tried to but a { after if but loads more errors come back!
Replace those 3 lines with these 4. You have a parenthesis error and a bracket error.
if (editingStyle == UITableViewCellEditingStyle.Delete) {
taskMgr.tasks.removeAtIndex(indexPath.row)
}
tblTasks.reloadData()
Also, make sure that you've properly set your UITableView dataSource and delegate. You can do this in IB or you can do this by replacing your existing viewDidLoad with:
override func viewDidLoad() {
super.viewDidLoad()
tblTasks.delegate = self
tblTasks.datasource = self
}
Related
I'm starting to learn swiftui and I've run into a problem that is both very basic and easily solvable in UIKit; but after spending days searching the internet and watching WWDC videos I've found no native solution.
The premise is simple: I have an array of songs I want to display in a list; when a user taps on a song view it should highlight the view on press, unhighlight after release, and then play the song (ie trigger an action). Sounds simple right?
Here's what I tried and spent way too much time on:
Using List(selection) + .onEvent(changed): I end up with a UUID (because i've only gotten selection to work with a UUID) that I then have to check against an array of songs to match AND the cell won't unhighlight/select itself; even when I try to manually set the State variable to nil or another generated UUID.
Using .onTap (either on or in the cell): I have to tap on the text of the cell to trigger onTap so I get a lot of taps that just don't work (because I have lots of white space in the cell). I also don't get a nice UI color change on press/release.
So after spending hours trying many different things I've finally come up with a solution and I basically wanted to create an account and share it to hopefully help other developers in my position. Because this so very annoyed me that something so basic took so much effort and time to do.
In the end the best solution I came up with was this:
Using ZStack and an empty button:
edit: I found I need to include and hide the content otherwise the button doesn't grow to fill the space (seems in lists it does for some reason). Though not sure what the hit on performance is of rendering the content twice when hiding it. Maybe a GeometryReader would work better?
struct SelectionView: ViewModifier {
let onSelect: () -> Void
func body(content: Content) -> some View {
ZStack (alignment: .leading) {
Button {
onSelect()
} label: {
content
.hidden()
}
content
}
}
}
extension View {
func onSelection(_ selection: #escaping () -> Void) -> some View {
self.modifier(SelectionView(onSelect: selection))
}
}
then to use it:
SongCell(song: song)
.onSelection {
// Do whatever action you want
}
No messing around with list selection, no weird tap hit boxes, and get the press/release color change. Basically put an empty button in a ZStack and trigger off it's action. Could possibly cause tap/touch issues with more complicated cells (?) but it does exactly what I need it to do for my basic app. I'm just not sure why it took so much effort and why apple doesn't support such a basic use case by default? If I've overlooked something native please do inform me. Thanks.
I got the basic idea what you are trying to do. I'm Going to show simple example. Maybe using this you will be able to find proper solution.
First let's create a color : -
#State var colorToShow : Color = Color.blue
Now in body we have our ZStack or Your cell that we want to deal with : -
ZStack{
colorToShow
}.frame(width: 50, height: 50).padding()
.onLongPressGesture(minimumDuration: 3) {
print("Process Complete")
colorToShow = .green
} onPressingChanged: { pressing in
if pressing {
print("Pressing")
colorToShow = .red
} else {
print("Pressing Released")
colorToShow = .blue
}
}
Here we are using .onLongPressGesture. You can set minimum duration on which you want to perform action. Now on process completion You set what you want to do. OnPressingChange give you a bool value that changes according to user is pressing that button or not. Show color change(Highlight) or do action while bool value is true. When user release button do action or unhighlight since bool value turns false.
Hope you find it useful.
I have multiple File Browser Item fields on one page of Application in Oracle Apex.
What happens: When I miss any Item for which validation error fires, I want to hold that file to the browser but I usually loose it if I get that validation error. Is there a solution for the same like other Items fields hold previous value except File Browser Item field. Please see below ss:
Anshul,
APEX 4.2 is very old and no longer supported. A later (or preferably latest) version of APEX will behave differently as Dan explained above.
Can you import your application into apex.oracle.com (which is running APEX 20.1) and you will probably see better results. Based on this you can hopefully use it as justification to upgrade your environment.
Regards,
David
Go to your page-level attributes and a function like the following in the Function and Global Variable Declaration:
function validateItems(request) {
var $file1 = $('#P68_FILE_1');
var $file2 = $('#P68_FILE_2');
var errorsFound = false;
if ($file1.val() === '') {
errorsFound = true;
// Show item in error state
}
if ($file2.val() === '') {
errorsFound = true;
// Show item in error state
}
if (!errorsFound) {
// I think doSubmit was the name of the function back then. If not, try apex.submit
doSubmit(request);
} else {
// Show error message at top of page, I'll use a generic alert for now
alert('You must select a file for each file selector.');
}
}
Then, right-click the Create button and select Create a Dynamic Action. Set the name of the Dynamic Action to Create button clicked.
For the Action, set Type to Execute JavaScript Code. Enter the following JS in code:
validateItems('CREATE');
Finally, ensure that Fire on Initialization is disabled.
Repeat the process for the Save button, but change the request value passed to validateItems to SAVE.
What is actually happening?
main.dart
In initState, we are calling server to get image from database, then add it into sink
var capturedImagesList = List<dynamic>();
#override
void initState() {
super.initState();
_bloc.getImages(); //
});
}
bloc class
final _urlImage = BehaviorSubject<List<dynamic>>();
get urlImageSink => _urlImage.sink;
get urlImageStream => _urlImage.stream;
Future getImages() async {
Response image = await _repo.getImages(); // call server
var imageResponse = Response.fromJson(image.body);
urlImageSink.add(imageResponse.images); // add image to sink
}
The retrieved image will be displayed in horizontal ListView.
When the + image is clicked, it will allow user to select an image from gallery, then placed beside the ListView as image below.
Everything works fine !
But when I click the + image again to add one more image, it throw us this error
[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception:
Concurrent modification during iteration: Instance(length:3) of
'_GrowableList'. E/flutter (32313): #0 List.addAll
(dart:core-patch/growable_array.dart:187:11)
main.dart
This is the code after image is selected from gallery.
#override
List<dynamic> userImage(File images) {
if (images != null) {
capturedImagesList.add(images.path); // add selected image to List
capturedImagesList.addAll(_bloc.urlImageStream.value); // add the server image to list
_bloc.urlImageSink.add(capturedImagesList); // add all images to list
}
return null;
}
Errror is pointed to this line
capturedImagesList.addAll(_bloc.urlImageStream.value);
Why it works for the first time, but failed for second time?
You could just do that
_bloc.urlImageSink.add([images])
And the image would reflected immediately in UI.
I think the problem is in this line
capturedImagesList.addAll(_bloc.urlImageStream.value);
this looks strange, you can't copy the stream into array, it won't work.
Did you check out this thread: Exception: Concurrent modification during iteration: Instance(length:17) of '_GrowableList'
I quote from the article:
This error means that you are adding or removing objects from a collection during iteration. This is not allowed since adding or removing items will change the collection size and mess up subsequent iteration.
So I don't see all the code, but could it be that when you add a picture via the add button, you clear the list or remove the current items?
Try to clear the array like this before doing addAll
_myLeaveRequests?.clear();
I have implemented code as per the google SDK documentation line by line in my app, but still when I click on google sign in button app shifts to new view controller with webview with blank screen. Have tried multiple solution found here : GIDSignIn white screen on iOS 91. But no lucks with resolving the problem , have attached the screen shot for getting closer look about the screen.
Following are the pods that I'm using,
Running XCode 9.1, iOS 10.0 and later. Kindly request someone to help.
Update: View Hierarchy
Update: viewDidLoad's code:
GIDSignIn.sharedInstance().uiDelegate = self
if self.isChangePassword {
self.addSignInView()
}
else {
self.addSignUpView()
}
fileprivate func addSignInView() {
guard let signInEmailView: SignInEmailView = Bundle.main.loadNibNamed(NibNames.SignInEmailView.rawValue, owner: self, options: nil)?[0] as? SignInEmailView
else {
return
}
signInEmailView.delegate = self
gaManager.trackScreen(screenName: ScreenNames.SignIn.rawValue)
self.animateView(signInEmailView)
}
fileprivate func addSignInView() {
guard let signInEmailView: SignInEmailView = Bundle.main.loadNibNamed(NibNames.SignInEmailView.rawValue, owner: self, options: nil)?[0] as? SignInEmailView
else {
return
}
signInEmailView.delegate = self
gaManager.trackScreen(screenName: ScreenNames.SignIn.rawValue)
self.animateView(signInEmailView)
}
I have the same problem. I use the UIAlertView to confirm user really want to do authorization. It will show the blank screen. If I remove the UIAlertView and show the authorization view directly. It works fine.
The problem also show in the Dropbox authorization screen.
If you not use UIAlertView , please try to pass the top most controller
https://github.com/dropbox/dropbox-sdk-obj-c/issues/182
Hope this can do some help.
Finally after so many days found the problem. I was showing splash view from my appDelegate using refrence of UIWindow which was adding and removing an imgview as subview to the window. So it was somehow messing with the UINavigation's stack and my view controller was not getting any reference to the UINavigationController. After removing that code it's working just fine. Also came to the solution that, if I want to show splash screen, as I can't use UIWindow's reference, I have to add new VC and write my all navigation code there. #TedYu Thank you very much for the help. :)
I'm getting started with TDD and got stuck testing a simple UITableViewController (using storyboards).
The tableView should have one row for every element in my model NSArray:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.sortedStories count];
}
My test for this is:
- (void)testTwoStoriesShouldLeadToTwoRowsInSectionZero
{
_sut.sortedStories = [self arrayWithTwoStories];
[_sut.tableView reloadData];
XCTAssertEqual([_sut tableView:_sut.tableView numberOfRowsInSection:0], 2, #"The number of rows should match the number of stories");
}
And I'm initializing my _sut in my test class from my storyboard like this:
- (void)setUp
{
[super setUp];
UIStoryboard *storyboard =
[UIStoryboard storyboardWithName:#"Main_iPhone"
bundle:nil];
_sut = [storyboard instantiateViewControllerWithIdentifier:
#"MyTableViewController"];
}
This works perfectly fine if there is no setup of the model in my production code. But after I added this default setup with seven stories in my UITableViewController's viewDidLoad method:
- (void)viewDidLoad
{
[super viewDidLoad];
self.sortedStories = [self sevenDefaultStories];
}
the test suddenly fails, stating that 'seven isn't equal to two'. The tableView seems not to reload the data, though I have the [_sut.tableView reloadData] in my test after changing the model.
What am I doing wrong?
I found it:
Though the tableViewController was instantiated via storyboard etc., the view had not been loaded yet!
So viewDidLoad also had not been called yet, when I 'changed' my model. But then, when I called [_sut.tableView reloadData] (which should make sure, the tableView would get synced with my model), this caused exactly the opposite: accessing the tableView made it necessary that the view got loaded, so NOW finally viewDidLoad was called on my tableViewController! And so my model got changed again, overwriting my nice test model with default values.
The solution was, to add [_sut view]; to the top of my test case. This makes sure that the view is already loaded when my test begins.
And, in my case, calling [_sut.tableView reloadData] wasn't necessary at all, since I'm only testing the dataSource method directly, not the actual tableView. N.B.:[_sut view] still needs to be called, because the dataSource method in my XCTAssertEqual() statement also triggers the view to be loaded, if that has not happened yet.
So the working test case looks like this:
- (void)testTwoStoriesShouldLeadToTwoRowsInSectionZero
{
[_sut view];
_sut.sortedStories = [self arrayWithTwoStories];
XCTAssertEqual([_sut tableView:_sut.tableView numberOfRowsInSection:0], 2, #"The number of rows should match the number of stories");
}
During test setup (my preferred solution):
[UIApplication sharedApplication].keyWindow.rootViewController = _sut; // Suck it UIKit
You may alternatively consider:
[[UIApplication sharedApplication].keyWindow addSubview:_sut.view]; // Hax
Note that UITableView may not render any cells unless it has been added to the view hierarchy. Similarly, UIViewController lifecycle methods may not be called unless it is added to the view controller hierarchy. I currently use "my preferred solution" above because it accomplishes both.