I am trying to self size DTAttributedTextContentView inside the collection cell based on its attributed text. The problem I face is that when I set attributedTextContentView width constraints like so:
attributedTextContentView.widthAnchor.constraint(lessThanOrEqualToConstant: 260)
it applies the whole constant width (in this case 260) to the textContentView, even if attributedString length is smaller than the width, leaving some extra space:
My question is, how to size the frame of DTAttributedTextContentView so that it just encloses the text that it contains?
Initially I used basic UITextView, but the scrolling of cells through collection view is not that smooth when there are multiple cells, and also it gives possibility to easy access the last line of the text inside, which I need for my app, so I would like to stick to DTAttributedTextContentView.
Here is the sample code for testing:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
configureCollectionView()
}
// MARK: - Collection view setup
let collectionView: UICollectionView = {
let layout = UICollectionViewCompositionalLayout { (section, environment) -> NSCollectionLayoutSection? in
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(10))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let group = NSCollectionLayoutGroup.vertical(layoutSize: itemSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
section.interGroupSpacing = 5
return section
}
layout.configuration.scrollDirection = .vertical
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.register(ConversationCollectionViewCell.self, forCellWithReuseIdentifier: "ConversationCell")
return collectionView
}()
private func configureCollectionView() {
collectionView.dataSource = self
collectionView.backgroundColor = .brown
view.addSubview(collectionView)
collectionView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
collectionView.topAnchor.constraint(equalTo: view.topAnchor),
collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
}
}
// MARK: - Collection Data Source
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ConversationCell", for: indexPath) as! ConversationCollectionViewCell
return cell
}
}
// MARK: - Collection View Custon Cell
final class ConversationCollectionViewCell: UICollectionViewCell, DTAttributedTextContentViewDelegate {
var mainCellContainerView = UIView()
var attributedTextContentView = DTAttributedTextContentView()
//MARK: - LIFECYCLE
override init(frame: CGRect) {
super.init(frame: frame)
setupmainCellContainerView()
setupAttributedTextContentView()
layoutIfNeeded()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - UI STEUP
private func setupmainCellContainerView() {
contentView.addSubview(mainCellContainerView)
mainCellContainerView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
mainCellContainerView.topAnchor.constraint(equalTo: contentView.topAnchor),
mainCellContainerView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
mainCellContainerView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
mainCellContainerView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
])
}
private func setupAttributedTextContentView() {
mainCellContainerView.addSubview(attributedTextContentView)
attributedTextContentView.backgroundColor = .systemIndigo
attributedTextContentView.delegate = self
attributedTextContentView.sizeToFit()
let attributedString = NSAttributedString(string: "Simple message for testing purpose @", attributes: [
.font: UIFont(name: "HelveticaNeue", size: 17),
.foregroundColor: UIColor.white,
.paragraphStyle: {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .left
paragraphStyle.lineBreakMode = .byWordWrapping
return paragraphStyle
}()
])
attributedTextContentView.attributedString = attributedString
attributedTextContentView.contentMode = .redraw
attributedTextContentView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
attributedTextContentView.widthAnchor.constraint(lessThanOrEqualToConstant: 260),
attributedTextContentView.topAnchor.constraint(equalTo: mainCellContainerView.topAnchor),
attributedTextContentView.bottomAnchor.constraint(equalTo: mainCellContainerView.bottomAnchor),
])
}
}
Swift
RSS for tagSwift is a powerful and intuitive programming language for Apple platforms and beyond.
Posts under Swift tag
200 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
I am doing the "Creating a card view" part of the ios development tutorials and for some reason I have this weird bug with previewing files.
When I click on any swiftUI files I have the error "Active scheme does not build this file", but then when I physically move the file to a different folder, or just somewhere else in general, the preview screen will reload and then display the preview with live updates.
This will then go away when I click on a different file and come back, but can be fixed by physically moving the file around again. This issue is blowing my mind as I've spent a couple hours just trying to add a new scheme which still does not work.
I would be so grateful for any answers
I have two models that are have a weird interaction:
@Model public final class Position: Equatable, Identifiable {
var zone: ZoneModel?
@Relationship(deleteRule: .cascade, inverse: \Item.positions)
var items = [Item]()
var name: String = ""
var weight: Int = 0
var weightAllowed: Int = 0
init(name: String, weightAllowed: Int) {
self.name = name
self.weightAllowed = weightAllowed
}
}
@Model public final class Item: Equatable, Identifiable {
var form: FormModel?
var positions: [Position]()
var count: Int = 0
var weight: Int = 0
init() {}
}
There are many other tables that are all connected, but these are the ones where the problems arise. The PositionModel is able to properly store and persist the items: [ItemModel] variable, but the ItemModel runs into a problem after the app closes.
I am getting this error in my SQL Stack Trace
no such column: t1.Z_6POSITIONS in "SELECT 0, t0.Z_PK FROM Z_5POSITIONS t1 JOIN ZPOSITION t0 ON t0.Z_PK = t1.Z_6POSITIONS WHERE t1.Z_5ITEMS = ? "
When looking at my sqlite database I see that the table name is not Z_5POSITIONS.Z_6POSITIONS, but it is Z_5POSITIONS.Z_7POSITIONS.
Index T-SQL:
CREATE INDEX "Z_5POSITIONS_Z_7POSITIONS_INDEX" ON "Z_5POSITIONS" (
"Z_7POSITIONS",
"Z_5ITEMS"
);
For extra context here is the SQL Stack Trace:
CoreData: annotation: Connecting to sqlite database file at "/~/default.store"
CoreData: sql: SELECT TBL_NAME FROM SQLITE_MASTER WHERE TBL_NAME = 'Z_METADATA'
TraceSQL(0x110e76a60): SELECT TBL_NAME FROM SQLITE_MASTER WHERE TBL_NAME = 'Z_METADATA'
CoreData: sql: pragma recursive_triggers=1
TraceSQL(0x110e76a60): pragma recursive_triggers=1
CoreData: sql: pragma journal_mode=wal
TraceSQL(0x110e76a60): pragma journal_mode=wal
CoreData: sql: SELECT 0, t0.Z_PK FROM Z_5POSITIONS t1 JOIN ZPOSITION t0 ON t0.Z_PK = t1.Z_6POSITIONS WHERE t1.Z_5ITEMS = ?
no such column: t1.Z_6POSITIONS in "SELECT 0, t0.Z_PK FROM Z_5POSITIONS t1 JOIN ZPOSITION t0 ON t0.Z_PK = t1.Z_6POSITIONS WHERE t1.Z_5ITEMS = ? "
CoreData: annotation: Disconnecting from sqlite database due to an error.
I have on automatic save, and also just to be sure and test it I am manually saving the added on ItemModel object. Every other SwiftData object is being properly saved, including the Items to the Position side to the many-to-many relationship, but the inverse isn't working.
Header(vm: vm, onSubmit: {
if vm.selected == nil {
vm.new.updateWeight(with: oc)
report.form?.addItem(vm.new)
do {
try context.save()
Logger.write("Save Successful.")
} catch {
Logger.write("Save error: \(error)")
}
vm.new = ItemModel()
} else { vm.selected = nil }
})
.padding(.vertical, 10)
I always get a successful save. But every time I close and reopen the app I run into the above issue.
Does anyone have any insight into this or maybe can spot something I have wrong off a look?
Is it possible to read the battery levels of my other devices from swift uizer like widgets? can you help?
Is it just me or is there like 2 windows that are on top of each other. I think this is a bug since I looked a countless of videos and no one else has this issue. Here's a picture of what I mean. as you can see on the glass window there seems to be 2 of them stuck together. Is there anyway of fixing this issue since its glitching out all my animations
thanks
After a drag/drop of an item into my app's collectionView, UIKit shows this progress UI while the data loads:
How do I cancel the loading of the dropped items when the user cancels?
The itemProvider.loadFileRepresentation completion block is always called without error. What am I missing?
coordinator.session.progress.cancellationHandler = {
Task { @MainActor in
// User canceled the dropped items loading
}
}
for item in coordinator.items {
item.dragItem.itemProvider.loadFileRepresentation(forTypeIdentifier: AVFileType.mov.rawValue) { [ weak self] (videoURL, error) in
// This completion block will get called even after operation was canceled.
}
}
I want to check if a given string matches a file pattern.
Does Swift have builtin support for filename globbing? Or is there any 3rd party packages for this?
I have multiple mobile applications, one developed in React Native and the other in Objective-C and Swift hybrid technology. I use my own system to send push notifications, and these notifications are left encrypted in the Apple queues. However, in any of my applications, I am unable to catch these messages in the code block where I decrypt them. As a result, users see the messages encrypted. While I can deterministically detect this issue on devices experiencing the offload feature from Apple, I've also noticed sporadic occurrences of this issue on devices not utilizing offload. Due to my security policies, I have no chance of sending messages unencrypted. I'm trying to understand why this is happening and need suggestions for a solution. Is there anyone who can help?
Additional Information:
I use my own system for push notifications.
Messages are left encrypted in the Apple queues.
I am unable to catch the messages in the code block where I decrypt them in one of the applications.
I can deterministically detect the issue on devices experiencing the offload feature.
I've noticed sporadic occurrences of this issue on devices not using offload.
Due to security policies, I have no chance of sending messages unencrypted.
I tried sending without offloading, and the messages arrived unencrypted I searched for a callback handler function on the Apple side - couldn't find one. To ensure notifications were sent correctly, I performed token checks in my database.
Hi, a few of my customers are facing a crash on using the app. I am unable to reproduce the issue myself. Can you please help. Here is the crash log of a user. Mine is a SwiftUI app.
Crash log of a user
I'm currently using Metal to create a game board with floating balloons; each balloon is a SKSpriteNode with an image of a balloon attached. The user touches and drags the balloon to a second balloon, merging the two. Exactly how they get merged is based on input from the user. I have a UISegmentedControl that pops up where the user selects one of four responses and the merge occurs. Currently, the UISegmentedControl pops up in the middle of the game board; however, I would like it to overlay on top of the first balloon instead.
I have tried this once the two balloons touch each other:
bubble1.physicsBody!.velocity = CGVector(dx: 0, dy: 0) // Stopping the balloon
requestView.frame.origin.x = bubble1.position.x
requestView.frame.origin.y = bubble1.position.y
Where requestView is a UIView (with the same dimensions of the balloon) with various subviews (including the UISegmentedControl) and bubble1 is the SKSpriteNode (balloon).
However, when I add the requestView as a subview of the game board, it does not overlay on top of the SKSpriteNode (bubble1). In fact, each time I try it, it doesn't even seem to appear in the same space relative to the location of the bubble1.
Any thoughts on what I might be doing wrong?
Thanks!
I get and int unix timestamp from database
and convert it to timeinterval as some instructions said.
But the result date is not correct.
the code is as follows:
let dateValue = try join.get(examDate);
print (dateValue)
let timeInterval = TimeInterval(dateValue);
print(timeInterval)
let date = Date(timeIntervalSince1970: timeInterval)
print(date)
the result is as follows:
1709942400000
1709942400000.0
56155-12-02 00:00:00 +0000
by converting 1709942400000 with js Date, we got the value:
>new Date(1709942400000)
2024-03-09T00:00:00.000Z
How can I properly convert unix timestamp to Date object?
Thanks in advance.
Hey devs!
I recently started a project, a macOS app, which is like a Remote Desktop app but only on local network.
For this I wanted to use the MultipeerConnectivity framework, and it's my first time using it. So I have already done the device discovery side that is working well as it is the easier part. Now I just need someone who knows how it works and who has time to explain me (as I couldn't find any documentation about this) how does work the OutputStream And InputStream in MC and if its a good choice for my needs. It has to be low latency and high resolution... I also have seen other frameworks such as WebRTC that I could combine with a local WebSocket Server, but as I'm new to live video streaming and that I don't know anyone that is experimented with this I wanted to ask there for your advices.
Thank you in advance, TR-MZ (just an unknown Indie dev).
Is there anyone able to help me worth some Swift coding. I have not done any coding since I was at university over 40 years ago, where I was taught Fortran 77, ICL Assembler and a bit of machine code, and bizarrely
BBC BASIC. The ICL computer filled a six story tower block, and the programs I developed were punched out on punch cards which we handed through a hatch to as technician and we came back a few days later to be told the program had failed at line 10!! my first job, I taught myself Kerningham and Ritchie C. Then I decided I hated coding and concentrated on hardware, networking, servers and systems and later own the internet. So I have not done any coding for5 around 40 years. Now that I have retired I have decided to develop an App to help me3 control my diabetes, so I am trying t5o learn Swift from an online tutorial, so I can’t ask the tutor what I have done wrong. Our second lesson is on functions, and I swear I have copied his code exactly as he had it, but it won’t run and gives the error message:
“Expressions are not allowed at the top level”
I am using an iMac 24-inch M1, running macOS Sonoma 14.2.1 and using Xcode 15.2 I am not sure what version of Swift it is, I assume it is the latest??
This the code ibn total:
import SwiftUI
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
var amount: Double = 120
var personCount = 2
func calculateATip(amount: Double) {
let tip = amount * 10 / 100
print(tip)
}
calculateATip(amount: 120)
It fails on the last line, what have I done wrong?
Looking for help identifying the following ui element or 'widget' in this app, the window is a sort of 'drop zone', you drag and drop files to it, it then displays the DnD'd files as a 'file stack' which is a ui element commonly seen in the Dock. Unable to find the api to create this. Surely it exists? (A screenshot is attached)
https://www.swift.org/getting-started/swiftui/
This training page let you understand the Vstack purpose but if you look at my own way of doing it I Made it disappear ??? is this a new release from Swift ?
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Why not try…")
.font(.largeTitle.bold())
Spacer()
Circle()
.fill(.blue)
.padding()
.overlay(
Image(systemName: "figure.archery")
.font(.system(size: 144))
.foregroundColor(.white)
)
Text("Archery!")
.font(.title)
Spacer()
}
}
#Preview {
ContentView()
}
I'm displaying file structure using DisclosureGroup.
And I encountered a memory leak problem.
Code
Node
Node represents a file or a folder.
isExpanded is used to indicate if the child nodes are visible.
If true, it will find its child nodes, which are set into children.
If false, it will clear children for releasing references.
class Node: ObservableObject, Identifiable, Hashable, CustomStringConvertible {
// ...
@Published var name: String
@Published var children: [Node]?
@Published var isExpanded = false {
willSet {
if self.isFile {
// This node represents a file.
// It does not have any children.
return
}
if newValue {
if children?.count == 0 {
DispatchQueue.main.async {
// get child nodes
self.children = childrenOf(self.url)
}
}
} else {
if children?.count != 0 {
DispatchQueue.main.async {
// collapse child nodes
self.children?.forEach { child in
child.isExpanded = false
}
// clear children when this node is collapsed
self.children = []
}
}
}
}
}
init(/*...*/) {
// ...
print("init \(name)")
}
deinit {
// ...
print("deinit \(name)")
}
// ...
}
For convenience, I print some messages when initializing Node and deinitializing Node.
TreeNode
TreeNode displays Node using DisclosureGroup.
struct TreeNode: View {
@ObservedObject var parent: Node
@ObservedObject var node: Node
var body: some View {
if node.isFile {
Text(node.name)
} else {
DisclosureGroup(
isExpanded: $node.isExpanded,
content: {
if node.isExpanded {
ForEach(node.children ?? []) { child in
TreeNode(parent: node, node: child)
}
}
},
label: {
FolderNodeView(node: node)
}
)
}
}
}
struct FolderNodeView: View {
@ObservedObject var node: Node
var body: some View {
Label(
title: { Text(node.name) },
icon: { Image(systemName: "folder.fill") }
)
}
}
I use if node.isExpanded for lazy loading.
When node.isExpanded is true, it will show node's children and print initialization messages. Otherwise, it will hide child nodes and print deinitialization messages.
But unexpectedly it does not print any deinitialization messages when the node is collapsed. This indicates that it retains references and therefore these Node objects still exists in memory causing memory leak.
Demo
When the node is expanded, its child nodes will be displayed after loading is completed. The code works correctly.
Then I collapsed the node, it didn't print any deinitialization messages. And when I expanded it again, it initialized new nodes and deinitialized the old nodes at this time. Deinitialization seems to be delayed.
So I guess TreeNode retains references when content is hidden.
Then I deleted TreeNode in ForEach.
DisclosureGroup(
isExpanded: $node.isExpanded,
content: {
if node.isExpanded {
ForEach(node.children ?? []) { child in
// TreeNode(parent: node, node: child)
}
}
},
label: {
FolderNodeView(node: node)
}
)
It cannot display the child nodes. But it released reference correctly.
So the code works expectedly.
After that, I tried to replace TreeNode with Text or Label.
I found that none of them released references immediately when I collapsed the node.
Why did this happen?
Any idea how to fix it?
Operating system: MacOS Sonoma 14.1
Description:
I am using ffmpeg's AVFoundation input device to read data from audio devices.
The ffmpeg code for this can be found at:
https://github.com/FFmpeg/FFmpeg/blob/master/libavdevice/avfoundation.m
I added some custom code that iterates over the formats available in audio_device and sets the active format based on the sample format or sample rate:
[audio_device setActiveFormat:selected_format];
This works for most of the cases, however, if the selected format is pcm_s16le instead of pcm_f32le the following error appears in the console:
[AudioConverter] Input data proc returned inconsistent 512 packets for 2048 bytes; at 8 bytes per packet, that is actually 256 packets.
No frames are returned causing ffmpeg to get stuck at:
// Take stream info from the first frame.
while (ctx->audio_frames_captured < 1) {
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, YES);
}
My guess is that the AVCaptureSession has an internal AudioConverter which tries to convert from pcm_f32le even if the audio device's active format was changed.
If I remove the setActiveFormat line and restart the program it will keep failing unless I restart the device.
Is there any workaround for this or something I should set in the AVCaptureSession?
Please help me understand this section!
I'm reading Finding the Dynamic Type in a Generic Context that has this snippet:
func printGenericInfo<T>(_ value: T) {
let t = type(of: value)
print("'\(value)' of type '\(t)'")
}
protocol P {}
extension String: P {}
let stringAsP: P = "Hello!"
printGenericInfo(stringAsP)
// 'Hello!' of type 'P'
... that's followed up by this sentence:
This unexpected result occurs because the call to type(of: value) inside printGenericInfo(_:) must return a metatype that is an instance of T.Type , but String.self (the expected dynamic type) is not an instance of P.Type (the concrete metatype of value).
1. How come String.self is not an instance of P when I can run this code?
func f(_ t: P.Type) { print("...") }
f(String.self)
2. Why does type(of:) return the concrete metatype outside but not inside generic functions?
print("'\(stringAsP)' of type '\(type(of: stringAsP))'")
// 'Hello!' of type 'String'
I am trying to use filter (I don't think map applies here, but I am not sure) to extract an element from an array of dictionaries which themselves contain dictionaries.
let participants = [
[
"id" : 1,
"team" : [
[
"name" : "John",
"job" : "teacher"
],
[
"name" : "Paul",
"job" : "coach"
],
[
"name" : "Mary",
"job" : "chef"
]
]
],
[
"id" : 7,
"team" : [
[
"name" : "Simon",
"job" : "engineer"
],
[
"name" : "Laura",
"job" : "writer"
],
[
"name" : "Peter",
"job" : "bartender"
]
]
],
[
"id" : 4,
"team" : [
[
"name" : "Igor",
"job" : "pianist"
],
[
"name" : "Mary",
"job" : "bartender"
],
[
"name" : "Denise",
"job" : "accountant"
]
]
]
]
I want to extract from the above array of dictionaries the element whose "team" value (which itself is an array of dictionaries) has an element whose "job" value is "writer". In other words, for the purpose of this exercise, I want the 2nd element of the participants array which is:
[
"id": 7,
"team": [
[
"name": "Simon",
"job": "engineer"
],
[
"name": "Laura",
"job": "writer"
],
[
"name": "Peter",
"job": "bartender"
]
]
]
How would I use map and/or filter to accomplish this?
HI
I haven't coded in a long time and I don't know how to use CodeX and now I can't move on from here, I don't know how to put the code in the right place in the code. :(
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
}
}
#Preview {
ContentView()
}
let range01INT1 = 100000 ... 199999
print("Range:",range01INT1,"Number of numbers", range01INT1.count)
Print command give me a error
let range01INT1 = 100000 ... 199999
print("Range:",range01INT1,"Number of numbers", range01INT1.count)
Expressions are not allowed at the top level
I know it's a stupid question, but I just can't get started.