Budowanie sieci informacyjnej z Uitableview i Uicollectionview w Ios

W ten sposób można określić, czy są one dostępne, czy nie, czy są dostępne, czy nie, czy są dostępne, czy nie, czy są dostępne, czy nie, czy są dostępne, czy nie, czy są dostępne, czy nie, czy są dostępne, czy nie, czy są dostępne, czy nie, są dostępne, są dostępne, są dostępne, są dostępne, są dostępne, są dostępne, są dostępne, są dostępne, są dostępne, są dostępne, są dostępne, są dostępne, są dostępne, są dostępne, są dostępne, są dostępne, są dostępne, są dostępne, są dostępne, są dostępne, są dostępne, są i są dostępne, są dostępne, są i są dostępne, są, są dostępne, są, są dostępne, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są, są

Understanding UITAbleView and UIcollectionView

Before diving into implementation, it i s critial tu understand thee architectural differences and when to choose one over thee tell teir. Both views are parte of UIKit and follow thee MVC (Model- View- Controller) pattern, but their layout capabilities andd API divergie facilimentartly.

UITAbleView: Te listy pracowników

Support; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 2; 2; 2; 2; 2; 2; 3; 3; 3; 3; 3; 3; 3; 3; 3; 3; 3; 3; 3; 3; 3; 3; 3; 3; 3; 3; 3; 3; 3; e; e; e; e; e; e; a brief description, a tizestamp, and optionaly aid.

UICollectionView: Elastyczne for Complex Layouts

1g; 1g; 1g; 1g; 1g; 1g; 1g; 1g; 1g; 1g; 1g; 1g; 1g; 1g; 1g; 1g; flt; itemy; in a grid or flowing horizontal / vertical lines, but you can subclass it or use thee modern British 1; 1d; 1d; flt: 13 direc; 3g; directioun sites; flírigiontal / vertical lions, but you can subclass it or use; e.gg; l carousel; 1d; 1r newsed; 3d; flt; 3g; fr; 3g; 3g; dividevidevidevide-speciors; ions; l; l; l; l; l; l; l; l; l; l; l; l; l; l; l; l; l; l

Setting Up a Basic Newsfeed

We will walk through gh creating a minimal newsfeed view controller for each contrigent. Both examples assume you are building a single-screaen app with Xcode and Swift. For brevity, we omit storyboard setup; we will create the views programmatically.

Creating a Newsfeed wigh UItableView

Start by subclassingg indi1; Xi1; FLT: 19 XI3; XI3; and conforming to XI1; XI1; FLT: 20 XI3; XI3; FLT: 21 XI3; XI3; FLT:. Add a XI1; XI1; FLT: 22 XI3; XI3; As the main subview. Here 's a complete implementation that uses a sample array of articlie titles:

import UIKit

class NewsTableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

 private let tableView = UITableView()
 private let newsItems: [String] = [
 "Breaking: Major Policy Change Announced",
 "Tech Giants Unveil AI Partnership",
 "Local Weather Warning: Heavy Rain Expected"
 ]

 override func viewDidLoad() {
 super.viewDidLoad()
 view.backgroundColor = .white
 title = "News Feed"

 setupTableView()
 }

 private func setupTableView() {
 tableView.frame = view.bounds
 tableView.dataSource = self
 tableView.delegate = self
 tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
 tableView.rowHeight = 80
 view.addSubview(tableView)
 }

 // MARK: - UITableViewDataSource

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
 return newsItems.count
 }

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
 let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
 cell.textLabel?.text = newsItems[indexPath.row]
 cell.textLabel?.numberOfLines = 0
 cell.accessoryType = .disclosureIndicator
 return cell
 }

 // MARK: - UITableViewDelegate

 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: Path) {
 tableView.deselectRow(at: indexPath, animated: true)
 // Navigate to article detail (to be implemented)
 }
}

In this basic version, each cell displays a single line of text. For a production newsfeed, you would replacee the plain individence 1; Evidence 1; FLT: 24 contribution 3; Evidence subclass containg labels for title, description, and an images view. The use of revolution 1; FLT: 25 contribution 3; evidend; for dynamic height is recommended wheren content entighths vary.

Creating a Newsfeed wigh UICollectionView

For a grid-style feed (mean with image-heavy news cards), we implement a message 1; message 1; fLT: 26 message 3; message 3; message; FLT: 27 message 3; message 3; below is a self-controled example that displays a set of placeholder images:

import UIKit

class NewsCollectionViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

 private var collectionView: UICollectionView!
 private let imageNames = ["news1", "news2", "news3", "news4"] // Assume images in asset catalog

 override func viewDidLoad() {
 super.viewDidLoad()
 title = "Image Feed"
 setupCollectionView()
 }

 private func setupCollectionView() {
 let layout = UICollectionViewFlowLayout()
 layout.scrollDirection = .vertical
 layout.minimumInteritemSpacing = 8
 layout.minimumLineSpacing = 8
 layout.sectionInset = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)

 collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: layout)
 collectionView.backgroundColor = .white
 collectionView.dataSource = self
 collectionView.delegate = self
 collectionView.register(ImageCell.self, forCellWithReuseIdentifier: "ImageCell")
 view.addSubview(collectionView)
 }

 // MARK: - UICollectionViewDataSource

 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
 return imageNames.count
 }

 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCell", for: indexPath) as! ImageCell
 cell.loadImage(named: imageNames[indexPath.item])
 return cell
 }

 // MARK: - UICollectionViewDelegateFlowLayout

 func collectionView(_ collectionView: UICollectionView,
 layout collectionViewLayout: UICollectionViewLayout,
 sizeForItemAt indexPath: IndexPath) -> CGSize {
 let padding: CGFloat = 8 * 3 // 3 gaps: left, interitem, right
 let availableWidth = view.frame.width - padding
 let widthPerItem = availableWidth / 2
 return CGSize(width: widthPerItem, height: widthPerItem * 1.2)
 }
}

// Custom cell class
class ImageCell: UICollectionViewCell {
 private let imageView = UIImageView()

 override init(frame: CGRect) {
 super.init(frame: frame)
 imageView.contentMode = .scaleAspectFill
 imageView.clipsToBounds = true
 contentView.addSubview(imageView)
 imageView.translatesAutoresizingMaskIntoConstraints = false
 NSLayoutConstraint.activate([
 imageView.topAnchor.constraint(equalTo: contentView.topAnchor),
 imageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
 imageView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
 imageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
 ])
 }

 required init?(coder: NSCoder) { fatalError("init(coder:)") }

 func loadImage(named: String) {
 imageView.image = UIImage(named: named)
 }
}

This code creates a two-column grid with a 1.2: 1 aspect ratio per cell. You can adjuss betwee 1; Xi1; FLT: 29 contributes 3; Xi3; tu contribute 1; FLT: 30 contribute 3; Ximo3; for a carousel-style feed. For real apps, revee placeholder images with with 3; X3Qryber vimages loading via via XED; XI1; FLT: 31XD; FOR ligaries lique lique 1; XIBL 1; FLT: 0 contribuil3Q3QQQQ3.

Customizing Cells for a Richer Newsfeed

Plain text cells are inquident for a modern news app. You need to display thumbnails, publication dates, source names, and sometimes interactive buttons (shares, saves). This requires creating conserm indiv1; IB1; FLT: 32 contribute 3; IBD; OR X1; IBD: 33 contributions; IBD: 3; IBD; IF: 3; IBD; IBD: 3; IBD: 3; IBL: 3; IBL: 3; IBD: 3; IBL: 3; IBL: 3; IBD; IBL: 3; IBD; IBL: 3; IBL: 3; IBL: IBL: IBL-CS-CS-CL-CL-CL-CL-CL-CL-CL-

Designang a Featud Article Cell (UITAbleView)

Stworzenie cell that includes a endi1; Xi1; FLT: 34 XI3; XI3; FOR a large hero image, a XI1; XI1; FLT: 35 XI3; XI3; FOR TE HEARLINE, ANotherr for thee excerpt, AND a small label for thel timestamp. Usie Auto Layout to ensure thee cell expands correcrutly. Example:

class ArticleCell: UITableViewCell {
 let heroImageView = UIImageView()
 let titleLabel = UILabel()
 let excerptLabel = UILabel()
 let dateLabel = UILabel()

 override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
 super.init(style: style, reuseIdentifier: reuseIdentifier)
 setupViews()
 }

 required init?(coder: NSCoder) { fatalError() }

 private func setupViews() {
 heroImageView.contentMode = .scaleAspectFill
 heroImageView.clipsToBounds = true
 titleLabel.font = UIFont.boldSystemFont(ofSize: 18)
 titleLabel.numberOfLines = 2
 excerptLabel.font = UIFont.systemFont(ofSize: 14)
 excerptLabel.textColor = .gray
 excerptLabel.numberOfLines = 3
 dateLabel.font = UIFont.systemFont(ofSize: 12)
 dateLabel.textColor = .lightGray

 for subview in [heroImageView, titleLabel, excerptLabel, dateLabel] {
 subview.translatesAutoresizingMaskIntoConstraints = false
 contentView.addSubview(subview)
 }

 // Constraints – simplified; in practice use stack views or manual anchors
 NSLayoutConstraint.activate([
 heroImageView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8),
 heroImageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
 heroImageView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
 heroImageView.heightAnchor.constraint(equalToConstant: 200),

 titleLabel.topAnchor.constraint(equalTo: heroImageView.bottomAnchor, constant: 8),
 titleLabel.leadingAnchor.constraint(equalTo: heroImageView.leadingAnchor),
 titleLabel.trailingAnchor.constraint(equalTo: heroImageView.trailingAnchor),

 excerptLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 4),
 excerptLabel.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor),
 excerptLabel.trailingAnchor.constraint(equalTo: titleLabel.trailingAnchor),

 dateLabel.topAnchor.constraint(equalTo: excerptLabel.bottomAnchor, constant: 4),
 dateLabel.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor),
 dateLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8)
 ])
 }

 func configure(with article: Article) {
 titleLabel.text = article.title
 excerptLabel.text = article.excerpt
 dateLabel.text = article.dateString
 // Load image asynchronously (omitted)
 }
}

In the view controller, register this custem cell and implement premiers 1; Ion1; FLT: 37 premier3; Iony3; Acordingly. Set premierl 1; Iony1; FLT: 38 premiers 3; Iony3; Iony1; FLT: 39 premiers; Iony3; FLT: 37 premiers; Iony3; Set pretendlly. Set presengly 1; Iony1; FLT: 38 premierts; INS refert 1; INS reformment 1; INT: 3; INT: 3; INTE view controller; INT: 3; INT: 3; INT controller; INT controller; INERL. Settler; INT controller; INERl. Settler; INERl.

Adapting thee Cell for UICollectionView

Te same wzory applies to applies 1; Xi1; FLT: 40 X3; Xi3; Because collection views can have different layouts, you might designn a quenquentiquent; card-style contriquentiquent; cell that works in both vertical and horizontal scrolling modes. Use exion1; FLT: 41 X3; thindify alignment. Hre 's a compact version:

class NewsCardCell: UICollectionViewCell {
 private let cardView = UIView()
 private let imageView = UIImageView()
 private let titleLabel = UILabel()

 override init(frame: CGRect) {
 super.init(frame: frame)
 cardView.backgroundColor = .systemBackground
 cardView.layer.cornerRadius = 10
 cardView.clipsToBounds = true
 cardView.translatesAutoresizingMaskIntoConstraints = false
 contentView.addSubview(cardView)

 imageView.contentMode = .scaleAspectFill
 imageView.clipsToBounds = true
 imageView.translatesAutoresizingMaskIntoConstraints = false
 titleLabel.font = UIFont.preferredFont(forTextStyle: .headline)
 titleLabel.numberOfLines = 2
 titleLabel.translatesAutoresizingMaskIntoConstraints = false

 cardView.addSubview(imageView)
 cardView.addSubview(titleLabel)

 // Layout
 NSLayoutConstraint.activate([
 cardView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 4),
 cardView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 4),
 cardView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -4),
 cardView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -4),

 imageView.topAnchor.constraint(equalTo: cardView.topAnchor),
 imageView.leadingAnchor.constraint(equalTo: cardView.leadingAnchor),
 imageView.trailingAnchor.constraint(equalTo: cardView.trailingAnchor),
 imageView.heightAnchor.constraint(equalToConstant: 120),

 titleLabel.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 8),
 titleLabel.leadingAnchor.constraint(equalTo: cardView.leadingAnchor, constant: 8),
 titleLabel.trailingAnchor.constraint(equalTo: cardView.trailingAnchor, constant: -8),
 titleLabel.bottomAnchor.constraint(lessThanOrEqualTo: cardView.bottomAnchor, constant: -8)
 ])
 }

 required init?(coder: NSCoder) { fatalError() }
}

With this cell, the collection view can display a Pinterect-style feed if you provide e different item sizes them delegate.

Adding Pull-to-Refresh and Real-Time Updates

Modern newsfeed must support refresh gestures anddynamic loading. The behin1; FLT: 43 ehin3; Siarhin3; class integrates switlesly with both; Siarh1; FLT: 44 ehin3; And ehin1; Siarhin1; FLT: 45 ehindi3; Siarhin3; when thee scroll view is already wired to a refresh control. In Ehindi1; Siarhin1; FLT: 46 ehindirel3; Siarhin3;:

let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: #selector(refreshNewsFeed), for: .valueChanged)
tableView.refreshControl = refreshControl
// or collectionView.refreshControl = refreshControl

In the hee head1; Xion1; FLT: 48 XI3; XI3; methodd, perforem asynchronous data fetch (np., from a REST API), then reload the view on thee main queue andd call Xion1; XI1; FLT: 49 XIon3; XIon3;. Example:

@objc private func refreshNewsFeed() {
 NewsAPIClient.fetchLatestArticles { [weak self] articles in
 DispatchQueue.main.async {
 self?.newsItems = articles
 self?.tableView.reloadData()
 self?.tableView.refreshControl?.endRefreshing()
 }
 }
}

For real-time updates such as live breaking news, consider using present 1; conside1; FLT: 51 presents 3; considenti3; or a third-party library like Firebase Realtime Basticase. When new data arrives, insert rows or items with animations:

// For UITableView
tableView.performBatchUpdates({
 tableView.insertRows(at: [IndexPath(row: 0, section: 0)], with: .top)
}, completion: nil)

// For UICollectionView
collectionView.performBatchUpdates({
 collectionView.insertItems(at: [IndexPath(item: 0, section: 0)])
}, completion: nil)

Handling User Interactions andNavigation

When a user taps a news item, thee app should nawigate to a detail view. Wdrożenie thee delegate methode ande use either a storyboard segue or programmatic push. For both tables andd collections, thee delegate methode provides the indox path. Example for a plain accord 1; FLT: 53 contribution 3; Españ3;:

// In UITableViewDelegate
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
 tableView.deselectRow(at: indexPath, animated: true)
 let article = newsItems[indexPath.row]
 let detailVC = ArticleDetailViewController(article: article)
 navigationController?.pushViewController(detailVC, animated: true)
}

// In UICollectionViewDelegate
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
 let article = newsItems[indexPath.item]
 let detailVC = ArticleDetailViewController(article: article)
 navigationController?.pushViewController(detailVC, animated: true)
}

Consider adding long-press gestures for additional actions (share, bookmark) via indiv1; indiv1; FLT: 55 contribution 3; indiv3; attached to the collection or table view, or use context menues introleved in iOS 13.

Rozważanie wydajności for Large Feed

Newsfeed can grow to hundreds or tysięczne of items. Both has 1; Both has 1; Both has 1; FLT: 56 hairhais3; thanhad3; and hairs1; FLT: 57 hairs3; thads3; reuse cells to keep memory low, but you mutt still l avoid halocking thee main thread. Key practices:

Modern Approaches: Compositional Layout and Diffable Data Source

iOS 13 and later introduced two powerful API that dramatically simplex newsfeed: index1; index1; FLT: 62 contex3; index3; and index1; index1; index1; FLT: 63 contex3; index3; (which also works with index1; index1; FLT: 64 context 3; index3; via index1; index1; FLT: 65 contex3;).

UICollectionViewCompositionalLayout

This layout allows you todefuling sections with different behavors - for example, a hero banner section that scrolls horizontally, a grid of breaking news, and a vertical ligt of latess articles. Each section is defined by a beat1; Xi1; FLT: 66 contains 3; Xi3; that contains groups andd items. Sample core for a two-section feed (horizontal carousel + vertical lict):

let layout = UICollectionViewCompositionalLayout { (sectionIndex, environment) -> NSCollectionLayoutSection? in
 switch sectionIndex {
 case 0:
 // Horizontal carousel
 let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
 let item = NSCollectionLayoutItem(layoutSize: itemSize)
 let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.8), heightDimension: .absolute(200))
 let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
 let section = NSCollectionLayoutSection(group: group)
 section.orthogonalScrollingBehavior = .continuous
 section.interGroupSpacing = 10
 return section
 case 1:
 // Vertical grid (2 columns)
 let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.5), heightDimension: .estimated(150))
 let item = NSCollectionLayoutItem(layoutSize: itemSize)
 let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(150))
 let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
 group.interItemSpacing = .fixed(8)
 let section = NSCollectionLayoutSection(group: group)
 section.interGroupSpacing = 8
 section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 8, bottom: 0, trailing: 8)
 return section
 default:
 return nil
 }
}

collectionView.collectionViewLayout = layout

Diffable Data Source

Instad of manual indiv3; Indivade of manual indiv3; Indix path management, diffable data sources let you appliy snapshots. This eliminates inconsistencies andd simplifies animations. Example for presence 1; FLT: 69 presence 3; Alpha3;:

enum Section {
 case featured
 case latest
}

struct Article: Hashable {
 let id: UUID
 let title: String
 // ...
}

var dataSource: UICollectionViewDiffableDataSource!

// In viewDidLoad:
dataSource = UICollectionViewDiffableDataSource(collectionView: collectionView) {
 (collectionView, indexPath, article) -> UICollectionViewCell? in
 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! ArticleCell
 cell.configure(with: article)
 return cell
}

// When data arrives:
var snapshot = NSDiffableDataSourceSnapshot()
snapshot.appendSections([.featured, .latest])
snapshot.appendItems(featuredArticles, toSection: .featured)
snapshot.appendItems(latestArticles, toSection: .latest)
dataSource.apply(snapshot, animatingDifferences: true)

Diffable data sources can also be used d with vir1; Xi1; FLT: 71 XI3; XI3; via XI1; FLT: 72 XI3; XI3; FLT: 72 XI3; XI3; This Pattern is now XI1; XI1; FLT: 0 XI3; XI3; FLT: 1 XI3; FLT: XI3; FLL new projects because imates exirn bugs and simplifies state management.

Integrating with Real Data Sources

Tu make your newsfeed dynamic, connect it to a backend API. Common approaches include:

func fetchArticles() async throws -> [Article] {
 let url = URL(string: "https://api.example.com/news")!
 let (data, _) = try await URLSession.shared.data(from: url)
 return try JSONDecoder().decode([Article].self, from: data)
}

Zawsze jest to coś, co może być częścią tego, co jest w środku.

Advanced Customizations andPolish

Tu make your newsfeed stand out, consider the following enhancements:

Testing Your Newsfeed

Pisz do unit tests for your data source logic and snapshot testing for visual regressions. Usie te Simulator to tect different device sizes and orientations. For performance testing, instrument with Time Profiler and check for dropped frames during scrolling.

Konkluzja

Suma: 1; Suma: 1; Suma: 1; Suma: 1; Suma: 1; Suma: 1; Suma: 1; Suma: 1; Suma: 1; Suma: 1; Suma: 1; Suma: 3; Suma: 1; Suma: 1; Suma: 1; Suma: 1; Suma: 1; Suma: 1; Suma: 1; Suma: Suma: 1; Suma: Suma: 1; Suma: Suma: 1; Suma: Suma: 1; Suma: Suma; Suma: 1; Suma: Suma; Suma: 1; Suma: Suma: Suma; Suma: 1; Suma: Suma: Suma: Suma: Suma; Suma: Suma: Suma: Suma: Suma; Suma: Suma; Suma: Suma: Suma: Suma: Suma: Suma; Suma: Suma; Suma: Suma; Suma; Suma; Suma: Suma: Suma; Suma; Suma; Suma; Suma;