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 >= %@", 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) -> 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?
Post
Replies
Boosts
Views
Activity
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) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> 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) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> 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) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> 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
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 {
		
		override func viewDidLoad() {
				super.viewDidLoad()
				let collection = ColorCollectionView(sectionHeadersPinToVisibleBounds: false)
				self.view.addSubview(collection)
				collection.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 8).isActive = true
				collection.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 8).isActive = true
				collection.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -8).isActive	= true
				collection.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -8).isActive	= true
				collection.translatesAutoresizingMaskIntoConstraints = false
				
				let colors: [UIColor] = [.systemGray, .systemGray2, .systemGray3,
																 .systemGray, .systemGray2, .systemGray3,
																 .systemGray, .systemGray2, .systemGray3,
																 .systemGray, .systemGray2, .systemGray3,
																 .systemGray, .systemGray2, .systemGray3,
																 .systemGray, .systemGray2, .systemGray3,
																 .systemGray, .systemGray2, .systemGray3,
																 .systemGray, .systemGray2, .systemGray3,
																 .systemGray, .systemGray2, .systemGray3,
																 .systemGray, .systemGray2, .systemGray3,
																 .systemGray, .systemGray2, .systemGray3,
																 .systemGray, .systemGray2, .systemGray3,]
				collection.colors = colors
		}
}
class ColorCollectionView: UICollectionView {
		var colors: [UIColor] = []
		
		var selectedColor: UIColor?
		
		var headerName: String?
		
		override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
				super.init(frame: frame, collectionViewLayout: layout)
				self.backgroundColor = .clear
				self.register(ColorCollectionViewCell.self, forCellWithReuseIdentifier:ColorCollectionViewCell.identifier)
				self.dataSource = self
				self.delegate = self
		}
		
		convenience init(sectionHeadersPinToVisibleBounds: Bool) {
				let layout = UICollectionViewFlowLayout()
				layout.sectionHeadersPinToVisibleBounds = sectionHeadersPinToVisibleBounds
				layout.scrollDirection = .vertical
				self.init(frame: .zero,	collectionViewLayout: layout)
				
		}
		
		required init?(coder aDecoder: NSCoder) {
				fatalError("init(coder:) has not been implemented")
		}
}
extension ColorCollectionView: UICollectionViewDelegateFlowLayout {
		
		func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
				return CGSize(width: collectionView.frame.width / 3, height: 60)
		}
		
		func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
												minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
				return CGFloat.leastNormalMagnitude
		}
		func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
				return 8
		}
}
extension ColorCollectionView: UICollectionViewDataSource {
		func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
				return colors.count
		}
		
		func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
				let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ColorCollectionViewCell.identifier, for: indexPath)
				let color = colors[indexPath.row]
				cell.backgroundColor = color
				return cell
		}
}
class ColorCollectionViewCell: UICollectionViewCell {
		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!
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
		HomeViewController
				ListViewController
						 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?
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): <NSCloudKitMirroringDelegate: 0x280b051e0>: Successfully set up CloudKit integration for store: <NSSQLCore: 0x280024a00> (URL: file:///private/var/mobile/Containers/Shared/AppGroup/89D9D17C-03DF-48E4-83C3-DB23A8FE0D6F/TestData.sqlite)
CoreData: warning: CoreData+CloudKit: -[NSCloudKitMirroringDelegate checkAndScheduleImportIfNecessary:]_block_invoke(2033): <NSCloudKitMirroringDelegate: 0x280b051e0>: Scheduling automated import with activity: <CKSchedulerActivity: 0x281f51590; additionalXPCActivityCriteria={
Priority = Utility;
}, containerID=<CKContainerID: 0x283c612e0; containerIdentifier=iCloud.io.test.testData, containerEnvironment="Sandbox">, 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?
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 {
		var body: some View {
				ScrollViewReader { proxy in
						VStack {
								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?
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?		func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
				let destination = Text("Destination")
				let host = UIHostingController(rootView: destination)
/*TODO: - Navigate to Destination
*navigationController.pushViewController(host, animated: true)/
}
UITableView
struct TableView: UIViewRepresentable {
		@State var rows = ["London", "Paris", "Oslo"]
		
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 {
		var body: some View {
				NavigationView {
						VStack {
								HStack {
										Text("Some other Views")
								}
								TableView()
						}
				}
		}
}
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.
My App has been rejected due to not having a functional link to Terms Of Use.
I have chosen Apple’s Standard License Agreement. Do I still need to have a Terms Of Use Policy ?
Thanks In advance.