Post

Replies

Boosts

Views

Activity

SwiftUI - View disappears if animated
I have asked this question on stack overflow. You may read it there, because I have included 2 GIFs that illustrates the problem. I am building a custom segmented control. This is the code that I have written. struct SegmentedControl: View { 		private var items: [String] = ["One", "Two", "Three"] 		 @Namespace var animation:Namespace.ID @State var selected: String = "One" var body: some View { ScrollView(.horizontal) { HStack { ForEach(items, id: \.self) { item in Button(action: { withAnimation(.spring()){ self.selected = item } }) { Text(item) .font(Font.subheadline.weight(.medium)) .foregroundColor(selected == item ? .white : .accentColor) .padding(.horizontal, 25) .padding(.vertical, 10) .background(zStack(item: item)) } } } .padding() } } private func zStack(item: String) -> some View { ZStack{ if selected == item { Color.accentColor .clipShape(Capsule()) .matchedGeometryEffect(id: "Tab", in: animation) } else { Color(.gray) .clipShape(Capsule()) }} } } A control is Blue when it is selected. However, sometimes if you navigate back and forth very fast, the Color.accentColor disappears Info, It is easier to test it on a physical device rather than a simulator.
0
0
992
Dec ’20
SwiftUI - Navigate from UITableView (UIViewRepresentable) to View
I have a NavigationView that contains a UItableView at the bottom. At the top, there are some more views. I am using UItableView because I need both of its trailing and leading swipe actions. Since the table view is a subview of NavigationView, is there any way to access it in UITableView, in its didSelectRowAt method?&#9;&#9;func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { &#9;&#9;&#9;&#9;let destination = Text("Destination") &#9;&#9;&#9;&#9;let host = UIHostingController(rootView: destination) /*TODO: - Navigate to Destination *navigationController.pushViewController(host, animated: true)/ } UITableView struct TableView: UIViewRepresentable { &#9;&#9;@State var rows = ["London", "Paris", "Oslo"] &#9;&#9; func makeUIView(context: Context) -> UITableView { let table = UITableView() table.register(UITableViewCell.self, forCellReuseIdentifier: "Cell") table.dataSource = context.coordinator table.delegate = context.coordinator return table } func updateUIView( uiView: UITableView, context: Context) { } func makeCoordinator() -> Coordinator { return Coordinator(rows: $rows) } class Coordinator: NSObject, UITableViewDataSource, UITableViewDelegate { @Binding var rows: [String] init(rows: Binding<[String]>) { self.rows = rows } func tableView( tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.rows.count } func tableView( tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") cell?.textLabel?.text = self.rows[indexPath.row] return cell! } func tableView( tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let destination = Text("Destination") let host = UIHostingController(rootView: destination) } func tableView( tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { let add = UIContextualAction(style: .normal,title: "Add") { (action, view, success) in success(true) } add.backgroundColor = .gray return UISwipeActionsConfiguration(actions: [add]) } func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { let remove = UIContextualAction(style: .normal,title: "Remove") { (action, view, success) in success(true) } remove.backgroundColor = .red let edit = UIContextualAction(style: .normal,title: "Edit") { (action, view, success) in success(true) } edit.backgroundColor = .gray let color = UIContextualAction(style: .normal, title: "Color") { (action, view, success) in success(true) } return UISwipeActionsConfiguration(actions: [remove, edit, color]) } } } View that contains the tableView struct ContentView: View { &#9;&#9;var body: some View { &#9;&#9;&#9;&#9;NavigationView { &#9;&#9;&#9;&#9;&#9;&#9;VStack { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;HStack { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Text("Some other Views") &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;TableView() &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;} &#9;&#9;} }
0
0
1.3k
Nov ’20
SwiftUI - ScrollViewReader's scrollTo does not scroll
I have a simple SwiftUI list that I want to scroll to a row when a user click on a button. This is my code that it suppose to work, but it does not do. struct ContentView: View { &#9;&#9;var body: some View { &#9;&#9;&#9;&#9;ScrollViewReader { proxy in &#9;&#9;&#9;&#9;&#9;&#9;VStack { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Button("Jump to #50") { proxy.scrollTo(5, anchor: .top) } List(0..<100) { i in Text("Example \(i)") .id(i) } } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } I tested it on iOS 14.2 both on simulator and a physical device. I read srollTo's documentation - https://developer.apple.com/documentation/swiftui/scrollviewproxy/scrollto(_:anchor:) but there is not much info. So how to scroll to a row, for example, row 50?
2
0
3.2k
Nov ’20
CoreData: warning: CoreData+CloudKit
I use NSPersistentCloudKitContainer. It seems that it the data synced in iCloud after a few seconds. However, I get the following warnings in the console. I do not understand what is it for. CoreData: warning: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _performSetupRequest:]_block_invoke(813): &lt;NSCloudKitMirroringDelegate: 0x280b051e0&gt;: Successfully set up CloudKit integration for store: &lt;NSSQLCore: 0x280024a00&gt; (URL: file:///private/var/mobile/Containers/Shared/AppGroup/89D9D17C-03DF-48E4-83C3-DB23A8FE0D6F/TestData.sqlite) CoreData: warning: CoreData+CloudKit: -[NSCloudKitMirroringDelegate checkAndScheduleImportIfNecessary:]_block_invoke(2033): &lt;NSCloudKitMirroringDelegate: 0x280b051e0&gt;: Scheduling automated import with activity: <CKSchedulerActivity: 0x281f51590; additionalXPCActivityCriteria={     Priority = Utility; }, containerID=&lt;CKContainerID: 0x283c612e0; containerIdentifier=iCloud.io.test.testData, containerEnvironment="Sandbox"&gt;, identifier=com.apple.coredata.cloudkit.activity.import, priority=2> Could you please explain what is this warning for and what should I do to fix it?
2
0
1.6k
Jul ’20
Navigate back from a UIViewController to its closest parent
I have a UITabBarViewController that is the rootViewController of the UIWindow. The tabBarViewController contains a UIViewController; lets call it HomeViewController. HomeViewController contains a UIViewController called ListViewController. ListViewController contains a UIViewController called ItemViewController UIWindow &#9;&#9;HomeViewController &#9;&#9;&#9;&#9;ListViewController &#9;&#9;&#9;&#9;&#9;&#9; ItemViewController The UITabBar is always visible. Pressing the Home tab returns to HomeViewController even if I am in ItemViewController. I do not want this. I want to navigate to ListViewController and then to HomeViewController should I press the Home tab bar again. How to navigate back from a UIViewController to its closest parent? In this case, How to return from ItemViewController to ListViewController if you press the Home tab bar once?
2
0
412
Jul ’20
Remove vertical space between UICollectionViewCell
I have a UICollectionView that has three cells on each row. There is no vertical space between the cells on all iPhones, except iPhone SE. There is like 1 point vertical space between the second and the last cells on iPhone SE. I do not understand where it comes from. How to get rid of it? class ViewController: UIViewController { &#9;&#9; &#9;&#9;override func viewDidLoad() { &#9;&#9;&#9;&#9;super.viewDidLoad() &#9;&#9;&#9;&#9;let collection = ColorCollectionView(sectionHeadersPinToVisibleBounds: false) &#9;&#9;&#9;&#9;self.view.addSubview(collection) &#9;&#9;&#9;&#9;collection.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 8).isActive = true &#9;&#9;&#9;&#9;collection.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 8).isActive = true &#9;&#9;&#9;&#9;collection.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -8).isActive&#9;= true &#9;&#9;&#9;&#9;collection.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -8).isActive&#9;= true &#9;&#9;&#9;&#9;collection.translatesAutoresizingMaskIntoConstraints = false &#9;&#9;&#9;&#9; &#9;&#9;&#9;&#9;let colors: [UIColor] = [.systemGray, .systemGray2, .systemGray3, &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; .systemGray, .systemGray2, .systemGray3, &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; .systemGray, .systemGray2, .systemGray3, &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; .systemGray, .systemGray2, .systemGray3, &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; .systemGray, .systemGray2, .systemGray3, &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; .systemGray, .systemGray2, .systemGray3, &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; .systemGray, .systemGray2, .systemGray3, &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; .systemGray, .systemGray2, .systemGray3, &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; .systemGray, .systemGray2, .systemGray3, &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; .systemGray, .systemGray2, .systemGray3, &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; .systemGray, .systemGray2, .systemGray3, &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; .systemGray, .systemGray2, .systemGray3,] &#9;&#9;&#9;&#9;collection.colors = colors &#9;&#9;} } class ColorCollectionView: UICollectionView { &#9;&#9;var colors: [UIColor] = [] &#9;&#9; &#9;&#9;var selectedColor: UIColor? &#9;&#9; &#9;&#9;var headerName: String? &#9;&#9; &#9;&#9;override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) { &#9;&#9;&#9;&#9;super.init(frame: frame, collectionViewLayout: layout) &#9;&#9;&#9;&#9;self.backgroundColor = .clear &#9;&#9;&#9;&#9;self.register(ColorCollectionViewCell.self, forCellWithReuseIdentifier:ColorCollectionViewCell.identifier) &#9;&#9;&#9;&#9;self.dataSource = self &#9;&#9;&#9;&#9;self.delegate = self &#9;&#9;} &#9;&#9; &#9;&#9;convenience init(sectionHeadersPinToVisibleBounds: Bool) { &#9;&#9;&#9;&#9;let layout = UICollectionViewFlowLayout() &#9;&#9;&#9;&#9;layout.sectionHeadersPinToVisibleBounds = sectionHeadersPinToVisibleBounds &#9;&#9;&#9;&#9;layout.scrollDirection = .vertical &#9;&#9;&#9;&#9;self.init(frame: .zero,&#9;collectionViewLayout: layout) &#9;&#9;&#9;&#9; &#9;&#9;} &#9;&#9; &#9;&#9;required init?(coder aDecoder: NSCoder) { &#9;&#9;&#9;&#9;fatalError("init(coder:) has not been implemented") &#9;&#9;} } extension ColorCollectionView: UICollectionViewDelegateFlowLayout { &#9;&#9; &#9;&#9;func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { &#9;&#9;&#9;&#9;return CGSize(width: collectionView.frame.width / 3, height: 60) &#9;&#9;} &#9;&#9; &#9;&#9;func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { &#9;&#9;&#9;&#9;return CGFloat.leastNormalMagnitude &#9;&#9;} &#9;&#9;func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { &#9;&#9;&#9;&#9;return 8 &#9;&#9;} } extension ColorCollectionView: UICollectionViewDataSource { &#9;&#9;func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { &#9;&#9;&#9;&#9;return colors.count &#9;&#9;} &#9;&#9; &#9;&#9;func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { &#9;&#9;&#9;&#9;let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ColorCollectionViewCell.identifier, for: indexPath) &#9;&#9;&#9;&#9;let color = colors[indexPath.row] &#9;&#9;&#9;&#9;cell.backgroundColor = color &#9;&#9;&#9;&#9;return cell &#9;&#9;} } class ColorCollectionViewCell: UICollectionViewCell { &#9;&#9;static let identifier = "ColorCollectionViewCell" } Update View's width: is 375.0 CollectionView's width: 359.0 CollectionVeiwCell's widht: 119.66666666666667 I appreciate any help!
0
0
2.2k
Jul ’20
Stack fullscreen viewController when presenting another viewController
I had asked this question long times ago on StackOveflow. You may read it there since it is more readble and includes imagesI have a UITabBarViewController with two tabs. I want to present a viewController fullscreen in one of the tabs. I have used the following code to do so. let navCtrl = UINavigationController(rootViewController: eventViewController) navCtrl.modalPresentationStyle = .fullScreen self.navigationController?.present(navCtrl, animated: true)It works. And EventViewController is fullscreen. However, when presenting another viewController in EventViewController, EventViewController is still fullscreen. But I want it to shrink in size and stack-up as it normally do. In order to do so, I have changed modalPresentationStyle to overCurrentContext let navCtrl = UINavigationController(rootViewController: eventViewController) navCtrl.modalPresentationStyle = .overCurrentContext self.navigationController?.present(navCtrl, animated: true)It does so, but it causes another problem: If I change tabs and dismiss EventViewController, the presenting viewController is black as described in this question (none of the answers helped).Basically I want the EventController to be fullscreen but shrink in size when presenting another controller in it. How to do so?A simple project with the same issue.class TabBarController: UITabBarController { override func viewDidLoad() { super.viewDidLoad() let ctrl = TabZeroViewController() ctrl.tabBarItem.image = UIImage(named: "archived-task") ctrl.tabBarItem.title = "One" let test = TabOneViewController() test.tabBarItem.image = UIImage(named: "Test") test.tabBarItem.title = "Test" let tabBarList = [ctrl, test ] self.viewControllers = tabBarList.map { let nav = UINavigationController(rootViewController: $0) nav.interactivePopGestureRecognizer?.isEnabled = true return nav } } } class TabZeroViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() self.tableView.delegate = self self.tableView.dataSource = self self.view.backgroundColor = .white } override func numberOfSections(in tableView: UITableView) -&gt; Int { return 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int { return 10 } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell { let cell = UITableViewCell() cell.textLabel?.text = "\(indexPath.row)" return cell } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let ctrl = ModalTableViewController() let nav = UINavigationController(rootViewController: ctrl) nav.modalPresentationStyle = .fullScreen self.navigationController?.present(nav, animated: true) } } class ModalTableViewController: UITableViewController { override func viewDidLoad() { self.view.backgroundColor = .red let button = UIButton() button.setTitle("Cancel", for: .normal) button.addTarget(self, action: #selector(dismissModal), for: .allEvents) let item = UIBarButtonItem() item.customView = button self.navigationItem.leftBarButtonItem = item self.tableView.dataSource = self self.tableView.delegate = self } @objc func dismissModal() { self.dismiss(animated: true, completion: nil) } override func numberOfSections(in tableView: UITableView) -&gt; Int { return 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int { return 10 } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell { let cell = UITableViewCell() cell.textLabel?.text = "Event" return cell } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let ctrl = EventViewController() let nav = UINavigationController(rootViewController: ctrl) nav.modalPresentationStyle = .overCurrentContext self.navigationController?.present(nav, animated: true) } } class TabOneViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } } class EventViewController: UITableViewController { override func viewDidLoad() { self.view.backgroundColor = .red let button = UIButton() button.setTitle("Cancel", for: .normal) button.addTarget(self, action: #selector(dismissModal), for: .allEvents) let item = UIBarButtonItem() item.customView = button self.navigationItem.leftBarButtonItem = item self.tableView.dataSource = self self.tableView.delegate = self } @objc func dismissModal() { self.dismiss(animated: true, completion: nil) } override func numberOfSections(in tableView: UITableView) -&gt; Int { return 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int { return 10 } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell { let cell = UITableViewCell() cell.textLabel?.text = "Event" return cell } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let ctrl = EventViewController() let nav = UINavigationController(rootViewController: ctrl) self.navigationController?.present(nav, animated: true) } }Add this code in willConnectTo of SceneDelegateif let windowScene = scene as? UIWindowScene { let window = UIWindow(windowScene: windowScene) window.rootViewController = TabBarController() self.window = window window.makeKeyAndVisible() }While you are on first tab, select a table cell to open the ModalTableViewController. And then change tabs and dismiss ModalTableViewController
4
0
3.5k
Apr ’20
iOS - today-widget does not get latest changes from host app
I have a NSManagedObject called Event shared between the host app and today extension. (In Target Membership, both the main app and the widget are checked). The host app and widget have the same App Group identifier and both share same Data Model(In Target Membership, both the main app and the widget are checked).When I launch(run) the widget in Xcode, it shows all the events (Event) that are already saved in the host app. However, when I add or edit an event, it appears in the host app as so but NOT in today-widget. If I relaunch the widget, all the events are shown including the last event that previously was not.This is the method that fetches events. It is defined in TodayViewController of the widget.private func fetchEvents(date: Date) { let predicates = NSCompoundPredicate(andPredicateWithSubpredicates: [ NSPredicate(format: "date = %@",Date().startOfDay as CVarArg), NSedicate(format: "startTime &gt;= %@", Date() as CVarArg) ]) if let ev = try? TPEvent.fetchAll(predicates: predicates, in: persistentManager.context) { events = ev } }This fetchEvents() is called in viewWillAppear and widgetPerformUpdate. persistentManaged.context is persistentContainer.viewContext.override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) fetchEvents(date: Date()) self.tableView.reloadData() } func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -&gt; Void)) { self.fetchEvents(date: Date() ) self.tableView.reloadData() completionHandler(NCUpdateResult.newData) }I have asked this question on Stackoverflow. It is more descriptive than this here.https://stackoverflow.com/questions/60104060/ios-today-widget-does-not-get-latest-changes-from-host-appWhat could be the issue and how to fix it?
3
0
1k
Feb ’20